Skip to content

Commit 16c8344

Browse files
committed
More cleanup
1 parent c9a925e commit 16c8344

File tree

5 files changed

+76
-50
lines changed

5 files changed

+76
-50
lines changed

src/compiler/checker.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6698,41 +6698,42 @@ namespace ts {
66986698
}
66996699

67006700
function tagNamesAreEquivalent(lhs: EntityName, rhs: EntityName): boolean {
6701-
if(lhs.kind !== rhs.kind) {
6701+
if (lhs.kind !== rhs.kind) {
67026702
return false;
67036703
}
6704-
if(lhs.kind === SyntaxKind.Identifier) {
6704+
6705+
if (lhs.kind === SyntaxKind.Identifier) {
67056706
return (<Identifier>lhs).text === (<Identifier>rhs).text;
67066707
}
6708+
67076709
return (<QualifiedName>lhs).right.text === (<QualifiedName>rhs).right.text &&
67086710
tagNamesAreEquivalent((<QualifiedName>lhs).left, (<QualifiedName>rhs).left);
67096711
}
67106712

67116713
function checkJsxElement(node: JsxElement) {
67126714
// Check that the closing tag matches
6713-
if(!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) {
6715+
if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) {
67146716
error(node.closingElement, Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, getTextOfNode(node.openingElement.tagName));
67156717
}
67166718

67176719
// Check attributes
67186720
checkJsxOpeningLikeElement(node.openingElement);
67196721

67206722
// Check children
6721-
let children = node.children;
6722-
for (var i = 0, n = children.length; i < n; i++) {
6723-
switch (children[i].kind) {
6723+
for(let child of node.children) {
6724+
switch (child.kind) {
67246725
case SyntaxKind.JsxExpression:
6725-
checkJsxExpression(<JsxExpression>children[i]);
6726+
checkJsxExpression(<JsxExpression>child);
67266727
break;
67276728
case SyntaxKind.JsxElement:
6728-
checkJsxElement(<JsxElement>children[i]);
6729+
checkJsxElement(<JsxElement>child);
67296730
break;
67306731
case SyntaxKind.JsxSelfClosingElement:
6731-
checkJsxSelfClosingElement(<JsxSelfClosingElement>children[i]);
6732+
checkJsxSelfClosingElement(<JsxSelfClosingElement>child);
67326733
break;
67336734
default:
67346735
// No checks for JSX Text
6735-
Debug.assert(children[i].kind === SyntaxKind.JsxText);
6736+
Debug.assert(child.kind === SyntaxKind.JsxText);
67366737
}
67376738
}
67386739

@@ -6742,7 +6743,7 @@ namespace ts {
67426743
/**
67436744
* Returns true iff the JSX element name would be a valid JS identifier, ignoring restrictions about keywords not being identifiers
67446745
*/
6745-
function isIdentifierLike(name: string) {
6746+
function isUnhyphenatedJsxName(name: string) {
67466747
// - is the only character supported in JSX attribute names that isn't valid in JavaScript identifiers
67476748
return name.indexOf('-') < 0;
67486749
}
@@ -6764,15 +6765,15 @@ namespace ts {
67646765
let correspondingPropType: Type = undefined;
67656766

67666767
// Look up the corresponding property for this attribute
6767-
if (elementAttributesType === emptyObjectType && isIdentifierLike(node.name.text)) {
6768+
if (elementAttributesType === emptyObjectType && isUnhyphenatedJsxName(node.name.text)) {
67686769
// If there is no 'props' property, you may not have non-"data-" attributes
67696770
error(node.parent, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, getJsxElementPropertiesName());
67706771
}
67716772
else if (elementAttributesType && !isTypeAny(elementAttributesType)) {
67726773
let correspondingPropSymbol = getPropertyOfType(elementAttributesType, node.name.text);
67736774
correspondingPropType = correspondingPropSymbol && getTypeOfSymbol(correspondingPropSymbol);
67746775
// If there's no corresponding property with this name, error
6775-
if (!correspondingPropType && isIdentifierLike(node.name.text)) {
6776+
if (!correspondingPropType && isUnhyphenatedJsxName(node.name.text)) {
67766777
error(node.name, Diagnostics.Property_0_does_not_exist_on_type_1, node.name.text, typeToString(elementAttributesType));
67776778
return unknownType;
67786779
}

src/compiler/emitter.ts

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,7 +1157,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
11571157
}
11581158
}
11591159

1160-
function emitJsxElement(openingNode: JsxOpeningElement|JsxSelfClosingElement, children?: JsxChild[]) {
1160+
function emitJsxElement(openingNode: JsxOpeningLikeElement, children?: JsxChild[]) {
11611161
// Call React.createElement(tag, ...
11621162
emitLeadingComments(openingNode);
11631163
write('React.createElement(');
@@ -1177,18 +1177,20 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
11771177
write('React.__spread(');
11781178

11791179
let haveOpenedObjectLiteral = false;
1180-
for (var i = 0; i < attrs.length; i++) {
1180+
for (let i = 0; i < attrs.length; i++) {
11811181
if (attrs[i].kind === SyntaxKind.JsxSpreadAttribute) {
11821182
// If this is the first argument, we need to emit a {} as the first argument
1183-
if(i === 0) {
1183+
if (i === 0) {
11841184
write('{}, ');
11851185
}
11861186

11871187
if (haveOpenedObjectLiteral) {
11881188
write('}');
11891189
haveOpenedObjectLiteral = false;
11901190
}
1191-
if (i > 0) write(', ');
1191+
if (i > 0) {
1192+
write(', ');
1193+
}
11921194
emit((<JsxSpreadAttribute>attrs[i]).expression);
11931195
}
11941196
else {
@@ -1198,7 +1200,9 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
11981200
}
11991201
else {
12001202
haveOpenedObjectLiteral = true;
1201-
if (i > 0) write(', ');
1203+
if (i > 0) {
1204+
write(', ');
1205+
}
12021206
write('{');
12031207
}
12041208
emitJsxAttribute(<JsxAttribute>attrs[i]);
@@ -1212,7 +1216,9 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
12121216
// One object literal with all the attributes in them
12131217
write('{');
12141218
for (var i = 0; i < attrs.length; i++) {
1215-
if (i > 0) write(', ');
1219+
if (i > 0) {
1220+
write(', ');
1221+
}
12161222
emitJsxAttribute(<JsxAttribute>attrs[i]);
12171223
}
12181224
write('}');
@@ -1223,10 +1229,14 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
12231229
if (children) {
12241230
for (var i = 0; i < children.length; i++) {
12251231
// Don't emit empty expressions
1226-
if (children[i].kind === SyntaxKind.JsxExpression && !((<JsxExpression>children[i]).expression)) continue;
1232+
if (children[i].kind === SyntaxKind.JsxExpression && !((<JsxExpression>children[i]).expression)) {
1233+
continue;
1234+
}
12271235

12281236
// Don't emit empty strings
1229-
if (children[i].kind === SyntaxKind.JsxText && !shouldEmitJsxText(<JsxText>children[i])) continue;
1237+
if (children[i].kind === SyntaxKind.JsxText && !shouldEmitJsxText(<JsxText>children[i])) {
1238+
continue;
1239+
}
12301240

12311241
write(', ');
12321242
emit(children[i]);
@@ -1261,8 +1271,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
12611271
}
12621272

12631273
function emitAttributes(attribs: NodeArray<JsxAttribute|JsxSpreadAttribute>) {
1264-
for (var i = 0, n = attribs.length; i < n; i++) {
1265-
if (i > 0) write(' ');
1274+
for (let i = 0, n = attribs.length; i < n; i++) {
1275+
if (i > 0) {
1276+
write(' ');
1277+
}
12661278

12671279
if (attribs[i].kind === SyntaxKind.JsxSpreadAttribute) {
12681280
emitJsxSpreadAttribute(<JsxSpreadAttribute>attribs[i]);
@@ -5869,11 +5881,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
58695881
}
58705882
}
58715883

5872-
function emitJsxElement(node: JsxElement|JsxSelfClosingElement) {
5884+
function emitJsxElement(node: JsxElement | JsxSelfClosingElement) {
58735885
switch (compilerOptions.jsx) {
58745886
case JsxEmit.React:
58755887
jsxEmitReact(node);
58765888
break;
5889+
case JsxEmit.Preserve:
58775890
// Fall back to preserve if None was specified (we'll error earlier)
58785891
default:
58795892
jsxEmitPreserve(node);
@@ -5892,8 +5905,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
58925905
let firstNonWhitespace = 0;
58935906
let lastNonWhitespace = -1;
58945907

5895-
for (var i = 0; i < text.length; i++) {
5896-
var c = text.charCodeAt(i);
5908+
// JSX trims whitespace at the end and beginning of lines, except that the
5909+
// start/end of a tag is considered a start/end of a line only if that line is
5910+
// on the same line as the closing tag. See examples in tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx
5911+
for (let i = 0; i < text.length; i++) {
5912+
let c = text.charCodeAt(i);
58975913
if (c === CharacterCodes.lineFeed || c === CharacterCodes.carriageReturn) {
58985914
if (firstNonWhitespace !== -1 && (lastNonWhitespace - firstNonWhitespace + 1 > 0)) {
58995915
lines.push(text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1));
@@ -5915,11 +5931,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
59155931
}
59165932

59175933
function shouldEmitJsxText(node: JsxText) {
5918-
if (compilerOptions.jsx === JsxEmit.React) {
5919-
return trimReactWhitespace(node).length > 0;
5920-
}
5921-
else {
5922-
return true;
5934+
switch (compilerOptions.jsx) {
5935+
case JsxEmit.React:
5936+
return trimReactWhitespace(node).length > 0;
5937+
case JsxEmit.Preserve:
5938+
default:
5939+
return true;
59235940
}
59245941
}
59255942

@@ -5939,7 +5956,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
59395956
}
59405957

59415958
function emitJsxExpression(node: JsxExpression) {
5942-
if (node.expression && node.expression.kind !== SyntaxKind.OmittedExpression) {
5959+
if (node.expression) {
59435960
switch (compilerOptions.jsx) {
59445961
case JsxEmit.Preserve:
59455962
default:

src/compiler/parser.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2858,11 +2858,12 @@ namespace ts {
28582858
}
28592859
return false;
28602860
});
2861+
28612862
if (isArrowFunctionInJsx) {
28622863
return Tristate.Unknown;
2863-
} else {
2864-
return Tristate.False;
28652864
}
2865+
2866+
return Tristate.False;
28662867
}
28672868

28682869
// This *could* be a parenthesized arrow function.

src/harness/harness.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,12 +1468,15 @@ module Harness {
14681468
if (isDTS(emittedFile.fileName)) {
14691469
// .d.ts file, add to declFiles emit
14701470
this.declFilesCode.push(emittedFile);
1471-
} else if (isJS(emittedFile.fileName) || isJSX(emittedFile.fileName)) {
1471+
}
1472+
else if (isJS(emittedFile.fileName) || isJSX(emittedFile.fileName)) {
14721473
// .js file, add to files
14731474
this.files.push(emittedFile);
1474-
} else if (isJSMap(emittedFile.fileName)) {
1475+
}
1476+
else if (isJSMap(emittedFile.fileName)) {
14751477
this.sourceMaps.push(emittedFile);
1476-
} else {
1478+
}
1479+
else {
14771480
throw new Error('Unrecognized file extension for file ' + emittedFile.fileName);
14781481
}
14791482
});

src/services/services.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2909,16 +2909,20 @@ namespace ts {
29092909
let isRightOfDot = false;
29102910
let isRightOfOpenTag = false;
29112911

2912-
if (contextToken && contextToken.kind === SyntaxKind.DotToken && contextToken.parent.kind === SyntaxKind.PropertyAccessExpression) {
2913-
node = (<PropertyAccessExpression>contextToken.parent).expression;
2914-
isRightOfDot = true;
2915-
}
2916-
else if (contextToken && contextToken.kind === SyntaxKind.DotToken && contextToken.parent.kind === SyntaxKind.QualifiedName) {
2917-
node = (<QualifiedName>contextToken.parent).left;
2918-
isRightOfDot = true;
2919-
} else if (contextToken && contextToken.kind === SyntaxKind.LessThanToken && sourceFile.languageVariant === LanguageVariant.JSX) {
2920-
isRightOfOpenTag = true;
2921-
location = contextToken;
2912+
if(contextToken) {
2913+
let kind = contextToken.kind;
2914+
if (kind === SyntaxKind.DotToken && contextToken.parent.kind === SyntaxKind.PropertyAccessExpression) {
2915+
node = (<PropertyAccessExpression>contextToken.parent).expression;
2916+
isRightOfDot = true;
2917+
}
2918+
else if (kind === SyntaxKind.DotToken && contextToken.parent.kind === SyntaxKind.QualifiedName) {
2919+
node = (<QualifiedName>contextToken.parent).left;
2920+
isRightOfDot = true;
2921+
}
2922+
else if (kind === SyntaxKind.LessThanToken && sourceFile.languageVariant === LanguageVariant.JSX) {
2923+
isRightOfOpenTag = true;
2924+
location = contextToken;
2925+
}
29222926
}
29232927

29242928
let semanticStart = new Date().getTime();
@@ -2930,11 +2934,11 @@ namespace ts {
29302934
getTypeScriptMemberSymbols();
29312935
}
29322936
else if (isRightOfOpenTag) {
2933-
// TODO include all in-scope value identifiers
29342937
let tagSymbols = typeChecker.getJsxIntrinsicTagNames();;
29352938
if (tryGetGlobalSymbols()) {
29362939
symbols = tagSymbols.concat(symbols.filter(s => !!(s.flags & SymbolFlags.Value)));
2937-
} else {
2940+
}
2941+
else {
29382942
symbols = tagSymbols;
29392943
}
29402944
isMemberCompletion = true;
@@ -3006,7 +3010,7 @@ namespace ts {
30063010

30073011
function tryGetGlobalSymbols(): boolean {
30083012
let containingObjectLiteral = getContainingObjectLiteralApplicableForCompletion(contextToken);
3009-
let jsxElement: JsxElement, jsxSelfClosingElement: JsxSelfClosingElement;
3013+
30103014
if (containingObjectLiteral) {
30113015
// Object literal expression, look up possible property names from contextual type
30123016
isMemberCompletion = true;

0 commit comments

Comments
 (0)