mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
CR feedback
This commit is contained in:
+15
-18
@@ -165,7 +165,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
|
||||
let JsxNames = {
|
||||
const JsxNames = {
|
||||
JSX: "JSX",
|
||||
IntrinsicElements: "IntrinsicElements",
|
||||
ElementClass: "ElementClass",
|
||||
@@ -5578,6 +5578,7 @@ namespace ts {
|
||||
case SyntaxKind.JsxAttribute:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxExpression:
|
||||
return forEachChild(node, isAssignedIn);
|
||||
}
|
||||
return false;
|
||||
@@ -6774,8 +6775,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
let firstChar = (<Identifier>tagName).text.charAt(0);
|
||||
return firstChar.toLowerCase() === firstChar;
|
||||
return isIntrinsicJsxName((<Identifier>tagName).text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6836,10 +6836,7 @@ namespace ts {
|
||||
/// Returns the type JSX.IntrinsicElements. May return `unknownType` if that type is not present.
|
||||
function getJsxIntrinsicElementsType() {
|
||||
if (!jsxIntrinsicElementsType) {
|
||||
let jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, undefined);
|
||||
let intrinsicsSymbol = jsxNamespace && getSymbol(jsxNamespace.exports, JsxNames.IntrinsicElements, SymbolFlags.Type);
|
||||
let intrinsicsType = intrinsicsSymbol && getDeclaredTypeOfSymbol(intrinsicsSymbol);
|
||||
jsxIntrinsicElementsType = intrinsicsType || unknownType;
|
||||
jsxIntrinsicElementsType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.IntrinsicElements) || unknownType;
|
||||
}
|
||||
return jsxIntrinsicElementsType;
|
||||
}
|
||||
@@ -6977,18 +6974,23 @@ namespace ts {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -7044,7 +7046,7 @@ namespace ts {
|
||||
return links.resolvedJsxType = getIndexTypeOfSymbol(sym, IndexKind.String);
|
||||
}
|
||||
else {
|
||||
// Resolution failed
|
||||
// Resolution failed, so we don't know
|
||||
return links.resolvedJsxType = anyType;
|
||||
}
|
||||
}
|
||||
@@ -7063,16 +7065,12 @@ namespace ts {
|
||||
return prop || unknownSymbol;
|
||||
}
|
||||
|
||||
let jsxElementClassType: Type = undefined;
|
||||
function getJsxGlobalElementClassType(): Type {
|
||||
let jsxNS = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined);
|
||||
if (jsxNS) {
|
||||
let sym = getSymbol(jsxNS.exports, JsxNames.ElementClass, SymbolFlags.Type);
|
||||
let elemClassType = sym && getDeclaredTypeOfSymbol(sym);
|
||||
return elemClassType;
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
if(!jsxElementClassType) {
|
||||
jsxElementClassType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.ElementClass);
|
||||
}
|
||||
return jsxElementClassType;
|
||||
}
|
||||
|
||||
/// Returns all the properties of the Jsx.IntrinsicElements interface
|
||||
@@ -7137,8 +7135,7 @@ namespace ts {
|
||||
return checkExpression(node.expression);
|
||||
}
|
||||
else {
|
||||
/// <Foo enabled /> is shorthand for <Foo enabled={true} />
|
||||
return booleanType;
|
||||
return unknownType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+31
-29
@@ -1113,20 +1113,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
/// 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) {
|
||||
var ch = (<Identifier>name).text.charAt(0);
|
||||
if (ch.toUpperCase() === ch) {
|
||||
emit(name);
|
||||
}
|
||||
else {
|
||||
write('"');
|
||||
emit(name);
|
||||
write('"');
|
||||
}
|
||||
return ch.toUpperCase() !== ch;
|
||||
if (name.kind === SyntaxKind.Identifier && isIntrinsicJsxName((<Identifier>name).text)) {
|
||||
write('"');
|
||||
emit(name);
|
||||
write('"');
|
||||
}
|
||||
else {
|
||||
Debug.assert(name.kind === SyntaxKind.QualifiedName);
|
||||
emit(name);
|
||||
}
|
||||
}
|
||||
@@ -1234,12 +1226,19 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
|
||||
// Don't emit empty strings
|
||||
if (children[i].kind === SyntaxKind.JsxText && !shouldEmitJsxText(<JsxText>children[i])) {
|
||||
continue;
|
||||
if (children[i].kind === SyntaxKind.JsxText) {
|
||||
let text = getTextToEmit(<JsxText>children[i]);
|
||||
if(text !== undefined) {
|
||||
write(', "');
|
||||
write(text);
|
||||
write('"');
|
||||
}
|
||||
}
|
||||
else {
|
||||
write(', ');
|
||||
emit(children[i]);
|
||||
}
|
||||
|
||||
write(', ');
|
||||
emit(children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5895,12 +5894,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
|
||||
function trimReactWhitespace(node: JsxText): string {
|
||||
// Could be empty string, do not use !node.formattedReactText
|
||||
if (node.formattedReactText !== undefined) {
|
||||
return node.formattedReactText;
|
||||
}
|
||||
|
||||
let lines: string[] = [];
|
||||
let result: string = undefined;
|
||||
let text = getTextOfNode(node);
|
||||
let firstNonWhitespace = 0;
|
||||
let lastNonWhitespace = -1;
|
||||
@@ -5910,9 +5904,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
// 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 (c === CharacterCodes.lineFeed || c === CharacterCodes.carriageReturn) {
|
||||
if (isLineBreak(c)) {
|
||||
if (firstNonWhitespace !== -1 && (lastNonWhitespace - firstNonWhitespace + 1 > 0)) {
|
||||
lines.push(text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1));
|
||||
let part = text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1);
|
||||
result = (result ? result + '" + \' \' + "' : '') + part;
|
||||
}
|
||||
firstNonWhitespace = -1;
|
||||
}
|
||||
@@ -5924,19 +5919,26 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
}
|
||||
if (firstNonWhitespace !== -1) {
|
||||
lines.push(text.substr(firstNonWhitespace));
|
||||
let part = text.substr(firstNonWhitespace);
|
||||
result = (result ? result + '" + \' \' + "' : '') + part;
|
||||
}
|
||||
|
||||
return node.formattedReactText = lines.join('" + \' \' + "');
|
||||
return result;
|
||||
}
|
||||
|
||||
function shouldEmitJsxText(node: JsxText) {
|
||||
function getTextToEmit(node: JsxText) {
|
||||
switch (compilerOptions.jsx) {
|
||||
case JsxEmit.React:
|
||||
return trimReactWhitespace(node).length > 0;
|
||||
let text = trimReactWhitespace(node);
|
||||
if (text.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
else {
|
||||
return text;
|
||||
}
|
||||
case JsxEmit.Preserve:
|
||||
default:
|
||||
return true;
|
||||
return getTextOfNode(node, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -657,7 +657,7 @@ namespace ts {
|
||||
sourceFile.languageVersion = languageVersion;
|
||||
sourceFile.fileName = normalizePath(fileName);
|
||||
sourceFile.flags = fileExtensionIs(sourceFile.fileName, ".d.ts") ? NodeFlags.DeclarationFile : 0;
|
||||
sourceFile.languageVariant = fileExtensionIs(sourceFile.fileName, ".tsx") ? LanguageVariant.JSX : LanguageVariant.Standard;
|
||||
sourceFile.languageVariant = isTsx(sourceFile.fileName) ? LanguageVariant.JSX : LanguageVariant.Standard;
|
||||
|
||||
return sourceFile;
|
||||
}
|
||||
@@ -1298,7 +1298,6 @@ namespace ts {
|
||||
case ParsingContext.HeritageClauses:
|
||||
return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.CloseBraceToken;
|
||||
case ParsingContext.JsxAttributes:
|
||||
// REMOVE -> // For error recovery, include } here (otherwise an over-braced {expr}} will close the surrounding statement block and mess up the entire file).
|
||||
return token === SyntaxKind.GreaterThanToken || token === SyntaxKind.SlashToken;
|
||||
case ParsingContext.JsxChildren:
|
||||
return token === SyntaxKind.LessThanToken && lookAhead(nextTokenIsSlash);
|
||||
@@ -3377,9 +3376,6 @@ namespace ts {
|
||||
node.name = parseIdentifierName();
|
||||
if (parseOptional(SyntaxKind.EqualsToken)) {
|
||||
switch (token) {
|
||||
case SyntaxKind.LessThanToken:
|
||||
node.initializer = parseJsxElementOrSelfClosingElement();
|
||||
break;
|
||||
case SyntaxKind.StringLiteral:
|
||||
node.initializer = parseLiteralNode();
|
||||
break;
|
||||
|
||||
@@ -877,8 +877,6 @@ namespace ts {
|
||||
|
||||
export interface JsxText extends Node {
|
||||
_jsxTextExpressionBrand: any;
|
||||
/// Used by the emitter to avoid recomputation
|
||||
formattedReactText?: string;
|
||||
}
|
||||
|
||||
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
|
||||
|
||||
@@ -1535,6 +1535,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);
|
||||
|
||||
@@ -2934,7 +2934,7 @@ namespace ts {
|
||||
getTypeScriptMemberSymbols();
|
||||
}
|
||||
else if (isRightOfOpenTag) {
|
||||
let tagSymbols = typeChecker.getJsxIntrinsicTagNames();;
|
||||
let tagSymbols = typeChecker.getJsxIntrinsicTagNames();
|
||||
if (tryGetGlobalSymbols()) {
|
||||
symbols = tagSymbols.concat(symbols.filter(s => !!(s.flags & SymbolFlags.Value)));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(39,17): error TS1005: '{' expected.
|
||||
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(39,23): error TS1005: '}' expected.
|
||||
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(39,29): error TS1005: '{' expected.
|
||||
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(39,57): error TS1109: Expression expected.
|
||||
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(39,58): error TS1109: Expression expected.
|
||||
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(41,1): error TS1003: Identifier expected.
|
||||
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(41,6): error TS1109: Expression expected.
|
||||
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(41,12): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx (8 errors) ====
|
||||
declare var React: any;
|
||||
declare var 日本語;
|
||||
declare var AbC_def;
|
||||
declare var LeftRight;
|
||||
declare var x;
|
||||
declare var a;
|
||||
declare var props;
|
||||
|
||||
<a />;
|
||||
|
||||
//<n:a n:v />; Namespace unsuported
|
||||
|
||||
//<a n:foo="bar"> {value} <b><c /></b></a>; Namespace unsuported
|
||||
|
||||
<a b={" "} c=" " d="&" e="id=1&group=2" f="�" g="{*;" h="&#x;" />;
|
||||
|
||||
<a b="¬anentity;" />;
|
||||
<a
|
||||
/>;
|
||||
|
||||
<日本語></日本語>;
|
||||
|
||||
<AbC_def
|
||||
test="&&">
|
||||
bar
|
||||
baz
|
||||
</AbC_def>;
|
||||
|
||||
<a b={x ? <c /> : <d />} />;
|
||||
|
||||
<a>{}</a>;
|
||||
|
||||
<a>{/* this is a comment */}</a>;
|
||||
|
||||
<div>@test content</div>;
|
||||
|
||||
<div><br />7x invalid-js-identifier</div>;
|
||||
|
||||
<LeftRight left=<a /> right=<b>monkeys /> gorillas</b> />;
|
||||
~
|
||||
!!! error TS1005: '{' expected.
|
||||
~~~~~
|
||||
!!! error TS1005: '}' expected.
|
||||
~
|
||||
!!! error TS1005: '{' expected.
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
|
||||
<a.b></a.b>;
|
||||
~
|
||||
!!! error TS1003: Identifier expected.
|
||||
~~
|
||||
!!! error TS1109: Expression expected.
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
|
||||
<a.b.c></a.b.c>;
|
||||
|
||||
(<div />) < x;
|
||||
|
||||
<div {...props} />;
|
||||
|
||||
<div {...props} post="attribute" />;
|
||||
|
||||
<div pre="leading" pre2="attribute" {...props}></div>;
|
||||
|
||||
<a> </a>;
|
||||
|
||||
@@ -71,8 +71,9 @@ baz
|
||||
<a></a>;
|
||||
<div>@test content</div>;
|
||||
<div><br />7x invalid-js-identifier</div>;
|
||||
<LeftRight left=<a /> right=<b>monkeys /> gorillas</b>/>;
|
||||
<a.b></a.b>;
|
||||
<LeftRight left={<a />} right={<b>monkeys /> gorillas</b> / > }/>
|
||||
< a.b > ;
|
||||
a.b > ;
|
||||
<a.b.c></a.b.c>;
|
||||
(<div />) < x;
|
||||
<div {...props}/>;
|
||||
|
||||
@@ -65,12 +65,13 @@ tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(28,10): error TS2304:
|
||||
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,7): error TS1003: Identifier 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 (70 errors) ====
|
||||
==== tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx (71 errors) ====
|
||||
declare var React: any;
|
||||
|
||||
</>;
|
||||
@@ -238,8 +239,10 @@ tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(35,21): error TS17002
|
||||
~
|
||||
!!! error TS1005: '{' expected.
|
||||
<a b=<}>;
|
||||
~
|
||||
!!! error TS1005: '{' expected.
|
||||
~
|
||||
!!! error TS1003: Identifier expected.
|
||||
!!! error TS1109: Expression expected.
|
||||
<a>}</a>;
|
||||
<a .../*hai*/asdf/>;
|
||||
~~~
|
||||
|
||||
@@ -76,6 +76,6 @@ var x = <div>one</div> /* intervening comment */ /* intervening comment */ <div>
|
||||
<a>></a>;
|
||||
<a> ></a>;
|
||||
<a b=>;
|
||||
<a b=< />/>}>;
|
||||
<a b={ < }>;
|
||||
<a>}</a>;
|
||||
<a /> .../*hai*/asdf/>;</></></>;
|
||||
<a /> .../*hai*/asdf/>;</></></></>;
|
||||
|
||||
Reference in New Issue
Block a user