Skip to content

Commit

Permalink
Merge branch 'master' into release-2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
mhegazy committed Apr 24, 2017
2 parents 54b5635 + a0abadb commit 3c3b73e
Show file tree
Hide file tree
Showing 88 changed files with 3,388 additions and 247 deletions.
233 changes: 155 additions & 78 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Expand Up @@ -2119,6 +2119,10 @@
"category": "Error",
"code": 2709
},
"'{0}' are specified twice. The attribute named '{0}' will be overwritten.": {
"category": "Error",
"code": 2710
},

"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/emitter.ts
Expand Up @@ -2457,7 +2457,7 @@ namespace ts {
let indentation: number;
for (const line of lines) {
for (let i = 0; i < line.length && (indentation === undefined || i < indentation); i++) {
if (!isWhiteSpace(line.charCodeAt(i))) {
if (!isWhiteSpaceLike(line.charCodeAt(i))) {
if (indentation === undefined || i < indentation) {
indentation = i;
break;
Expand Down
7 changes: 6 additions & 1 deletion src/compiler/parser.ts
Expand Up @@ -3828,13 +3828,15 @@ namespace ts {

function parseJsxText(): JsxText {
const node = <JsxText>createNode(SyntaxKind.JsxText, scanner.getStartPos());
node.containsOnlyWhiteSpaces = currentToken === SyntaxKind.JsxTextAllWhiteSpaces;
currentToken = scanner.scanJsxToken();
return finishNode(node);
}

function parseJsxChild(): JsxChild {
switch (token()) {
case SyntaxKind.JsxText:
case SyntaxKind.JsxTextAllWhiteSpaces:
return parseJsxText();
case SyntaxKind.OpenBraceToken:
return parseJsxExpression(/*inExpressionContext*/ false);
Expand Down Expand Up @@ -3864,7 +3866,10 @@ namespace ts {
else if (token() === SyntaxKind.ConflictMarkerTrivia) {
break;
}
result.push(parseJsxChild());
const child = parseJsxChild();
if (child) {
result.push(child);
}
}

result.end = scanner.getTokenPos();
Expand Down
29 changes: 24 additions & 5 deletions src/compiler/scanner.ts
Expand Up @@ -367,7 +367,7 @@ namespace ts {
return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position);
}

export function isWhiteSpace(ch: number): boolean {
export function isWhiteSpaceLike(ch: number): boolean {
return isWhiteSpaceSingleLine(ch) || isLineBreak(ch);
}

Expand Down Expand Up @@ -512,7 +512,7 @@ namespace ts {
break;

default:
if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpace(ch))) {
if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpaceLike(ch))) {
pos++;
continue;
}
Expand Down Expand Up @@ -694,7 +694,7 @@ namespace ts {
}
break scan;
default:
if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpace(ch))) {
if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpaceLike(ch))) {
if (hasPendingCommentRange && isLineBreak(ch)) {
pendingHasTrailingNewLine = true;
}
Expand Down Expand Up @@ -1727,8 +1727,12 @@ namespace ts {
return token = SyntaxKind.OpenBraceToken;
}

// First non-whitespace character on this line.
let firstNonWhitespace = 0;
// These initial values are special because the first line is:
// firstNonWhitespace = 0 to indicate that we want leading whitspace,

while (pos < end) {
pos++;
char = text.charCodeAt(pos);
if (char === CharacterCodes.openBrace) {
break;
Expand All @@ -1740,8 +1744,23 @@ namespace ts {
}
break;
}

// FirstNonWhitespace is 0, then we only see whitespaces so far. If we see a linebreak, we want to ignore that whitespaces.
// i.e (- : whitespace)
// <div>----
// </div> becomes <div></div>
//
// <div>----</div> becomes <div>----</div>
if (isLineBreak(char) && firstNonWhitespace === 0) {
firstNonWhitespace = -1;
}
else if (!isWhiteSpaceLike(char)) {
firstNonWhitespace = pos;
}
pos++;
}
return token = SyntaxKind.JsxText;

return firstNonWhitespace === -1 ? SyntaxKind.JsxTextAllWhiteSpaces : SyntaxKind.JsxText;
}

// Scans a JSX identifier; these differ from normal identifiers in that
Expand Down
4 changes: 3 additions & 1 deletion src/compiler/types.ts
Expand Up @@ -10,7 +10,7 @@ namespace ts {

/** ES6 Map interface. */
export interface Map<T> {
get(key: string): T;
get(key: string): T | undefined;
has(key: string): boolean;
set(key: string, value: T): this;
delete(key: string): boolean;
Expand Down Expand Up @@ -65,6 +65,7 @@ namespace ts {
NumericLiteral,
StringLiteral,
JsxText,
JsxTextAllWhiteSpaces,
RegularExpressionLiteral,
NoSubstitutionTemplateLiteral,
// Pseudo-literals
Expand Down Expand Up @@ -1572,6 +1573,7 @@ namespace ts {

export interface JsxText extends Node {
kind: SyntaxKind.JsxText;
containsOnlyWhiteSpaces: boolean;
parent?: JsxElement;
}

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/utilities.ts
Expand Up @@ -1870,7 +1870,7 @@ namespace ts {
}
}

export function getAncestor(node: Node | undefined, kind: SyntaxKind): Node {
export function getAncestor(node: Node | undefined, kind: SyntaxKind): Node | undefined {
while (node) {
if (node.kind === kind) {
return node;
Expand Down
35 changes: 35 additions & 0 deletions src/lib/dom.iterable.d.ts
Expand Up @@ -21,6 +21,22 @@ interface FormData {
[Symbol.iterator](): IterableIterator<string | File>;
}

interface Headers {
[Symbol.iterator](): IterableIterator<[string, string]>;
/**
* Returns an iterator allowing to go through all key/value pairs contained in this object.
*/
entries(): IterableIterator<[string, string]>;
/**
* Returns an iterator allowing to go through all keys f the key/value pairs contained in this object.
*/
keys(): IterableIterator<string>;
/**
* Returns an iterator allowing to go through all values of the key/value pairs contained in this object.
*/
values(): IterableIterator<string>;
}

interface NodeList {
/**
* Returns an array of key, value pairs for every entry in the list
Expand Down Expand Up @@ -70,3 +86,22 @@ interface NodeListOf<TNode extends Node> {

[Symbol.iterator](): IterableIterator<TNode>;
}

interface URLSearchParams {
/**
* Returns an array of key, value pairs for every entry in the search params
*/
entries(): IterableIterator<[string, string]>;
/**
* Returns a list of keys in the search params
*/
keys(): IterableIterator<string>;
/**
* Returns a list of values in the search params
*/
values(): IterableIterator<string>;
/**
* iterate over key/value pairs
*/
[Symbol.iterator](): IterableIterator<[string, string]>;
}
2 changes: 1 addition & 1 deletion src/services/formatting/smartIndenter.ts
Expand Up @@ -54,7 +54,7 @@ namespace ts.formatting {
let current = position;
while (current > 0) {
const char = sourceFile.text.charCodeAt(current);
if (!isWhiteSpace(char)) {
if (!isWhiteSpaceLike(char)) {
break;
}
current--;
Expand Down
17 changes: 14 additions & 3 deletions src/services/importTracker.ts
Expand Up @@ -387,6 +387,7 @@ namespace ts.FindAllReferences {
symbol: Symbol;
exportInfo: ExportInfo;
}

/**
* Given a local reference, we might notice that it's an import/export and recursively search for references of that.
* If at an import, look locally for the symbol it imports.
Expand All @@ -398,7 +399,7 @@ namespace ts.FindAllReferences {
return comingFromExport ? getExport() : getExport() || getImport();

function getExport(): ExportedSymbol | ImportedSymbol | undefined {
const { parent } = node;
const parent = node.parent!;
if (symbol.flags & SymbolFlags.Export) {
if (parent.kind === SyntaxKind.PropertyAccessExpression) {
// When accessing an export of a JS module, there's no alias. The symbol will still be flagged as an export even though we're at the use.
Expand All @@ -414,8 +415,8 @@ namespace ts.FindAllReferences {
}
}
else {
const exportNode = parent.kind === SyntaxKind.VariableDeclaration ? getAncestor(parent, SyntaxKind.VariableStatement) : parent;
if (hasModifier(exportNode, ModifierFlags.Export)) {
const exportNode = getExportNode(parent);
if (exportNode && hasModifier(exportNode, ModifierFlags.Export)) {
if (exportNode.kind === SyntaxKind.ImportEqualsDeclaration && (exportNode as ImportEqualsDeclaration).moduleReference === node) {
// We're at `Y` in `export import X = Y`. This is not the exported symbol, the left-hand-side is. So treat this as an import statement.
if (comingFromExport) {
Expand Down Expand Up @@ -492,6 +493,16 @@ namespace ts.FindAllReferences {
}
}

// If a reference is a variable declaration, the exported node would be the variable statement.
function getExportNode(parent: Node): Node | undefined {
if (parent.kind === SyntaxKind.VariableDeclaration) {
const p = parent as ts.VariableDeclaration;
return p.parent.kind === ts.SyntaxKind.CatchClause ? undefined : p.parent.parent.kind === SyntaxKind.VariableStatement ? p.parent.parent : undefined;
} else {
return parent;
}
}

function isNodeImport(node: Node): { isNamedImport: boolean } | undefined {
const { parent } = node;
switch (parent.kind) {
Expand Down
2 changes: 1 addition & 1 deletion src/services/textChanges.ts
Expand Up @@ -608,7 +608,7 @@ namespace ts.textChanges {
if (force || !isTrivia(s)) {
this.lastNonTriviaPosition = this.writer.getTextPos();
let i = 0;
while (isWhiteSpace(s.charCodeAt(s.length - i - 1))) {
while (isWhiteSpaceLike(s.charCodeAt(s.length - i - 1))) {
i++;
}
// trim trailing whitespaces
Expand Down
2 changes: 1 addition & 1 deletion src/services/utilities.ts
Expand Up @@ -1380,7 +1380,7 @@ namespace ts {
}

export function getFirstNonSpaceCharacterPosition(text: string, position: number) {
while (isWhiteSpace(text.charCodeAt(position))) {
while (isWhiteSpaceLike(text.charCodeAt(position))) {
position += 1;
}
return position;
Expand Down
39 changes: 39 additions & 0 deletions tests/baselines/reference/checkJsxChildrenProperty1.js
@@ -0,0 +1,39 @@
//// [file.tsx]
import React = require('react');

interface Prop {
a: number,
b: string,
children: string | JSX.Element
}

function Comp(p: Prop) {
return <div>{p.b}</div>;
}

// OK
let k = <Comp a={10} b="hi" children ="lol" />;
let k1 =
<Comp a={10} b="hi">
hi hi hi!
</Comp>;
let k2 =
<Comp a={10} b="hi">
<div>hi hi hi!</div>
</Comp>;

//// [file.jsx]
"use strict";
exports.__esModule = true;
var React = require("react");
function Comp(p) {
return <div>{p.b}</div>;
}
// OK
var k = <Comp a={10} b="hi" children="lol"/>;
var k1 = <Comp a={10} b="hi">
hi hi hi!
</Comp>;
var k2 = <Comp a={10} b="hi">
<div>hi hi hi!</div>
</Comp>;
67 changes: 67 additions & 0 deletions tests/baselines/reference/checkJsxChildrenProperty1.symbols
@@ -0,0 +1,67 @@
=== tests/cases/conformance/jsx/file.tsx ===
import React = require('react');
>React : Symbol(React, Decl(file.tsx, 0, 0))

interface Prop {
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))

a: number,
>a : Symbol(Prop.a, Decl(file.tsx, 2, 16))

b: string,
>b : Symbol(Prop.b, Decl(file.tsx, 3, 14))

children: string | JSX.Element
>children : Symbol(Prop.children, Decl(file.tsx, 4, 14))
>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1))
>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27))
}

function Comp(p: Prop) {
>Comp : Symbol(Comp, Decl(file.tsx, 6, 1))
>p : Symbol(p, Decl(file.tsx, 8, 14))
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))

return <div>{p.b}</div>;
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
>p.b : Symbol(Prop.b, Decl(file.tsx, 3, 14))
>p : Symbol(p, Decl(file.tsx, 8, 14))
>b : Symbol(Prop.b, Decl(file.tsx, 3, 14))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
}

// OK
let k = <Comp a={10} b="hi" children ="lol" />;
>k : Symbol(k, Decl(file.tsx, 13, 3))
>Comp : Symbol(Comp, Decl(file.tsx, 6, 1))
>a : Symbol(a, Decl(file.tsx, 13, 13))
>b : Symbol(b, Decl(file.tsx, 13, 20))
>children : Symbol(children, Decl(file.tsx, 13, 27))

let k1 =
>k1 : Symbol(k1, Decl(file.tsx, 14, 3))

<Comp a={10} b="hi">
>Comp : Symbol(Comp, Decl(file.tsx, 6, 1))
>a : Symbol(a, Decl(file.tsx, 15, 9))
>b : Symbol(b, Decl(file.tsx, 15, 16))

hi hi hi!
</Comp>;
>Comp : Symbol(Comp, Decl(file.tsx, 6, 1))

let k2 =
>k2 : Symbol(k2, Decl(file.tsx, 18, 3))

<Comp a={10} b="hi">
>Comp : Symbol(Comp, Decl(file.tsx, 6, 1))
>a : Symbol(a, Decl(file.tsx, 19, 9))
>b : Symbol(b, Decl(file.tsx, 19, 16))

<div>hi hi hi!</div>
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))

</Comp>;
>Comp : Symbol(Comp, Decl(file.tsx, 6, 1))

0 comments on commit 3c3b73e

Please sign in to comment.