Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Using overload for JSX stateless function component #11871

Closed
wants to merge 73 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
618da6f
Rename resolvedJsxType to be resolvedJSXElementAttributesType for cla…
Sep 30, 2016
70ea640
Create JsxAttributes which is similar to an ObjectLiteralExpression
Oct 4, 2016
8d02f9c
Add JsxOpeningLikeElement to CallLikeExpression
Oct 4, 2016
07c60a3
Rename parameters in resolveJsxElementAttributesType function
Oct 4, 2016
aeb7a3a
Split get attributes of intrinsic element and custom element
Oct 10, 2016
d263318
Rename getJsxElementAttributesType to getAttributesTypeFromJsxOpening…
Oct 11, 2016
cd0aabd
Check JsxAttributes of an intrinsic element
Oct 4, 2016
9b8b854
Using overload resolution logic when trying to pick a signature of a …
Oct 13, 2016
6b0d648
Add and update comments
Oct 17, 2016
fab4a84
Clean up prototyping overload-react
Oct 17, 2016
790ce8c
Update react.d.ts that is used in testing
Oct 18, 2016
999a585
Update comment
Oct 18, 2016
6d283b0
Change the type of default attribute (without initializer) to be true…
Oct 18, 2016
2cb95fc
Add tests: using spread-type in React.Component
Oct 18, 2016
a7c405e
Update baselines: using spread-type in React.Component
Oct 18, 2016
8d2fcc0
Add tests: optional property and overwrite spread property
Oct 18, 2016
2dc82cd
Update baselines: optional property and overwrite spread property
Oct 18, 2016
2a3b43b
Update react lib file for testing
Oct 20, 2016
2f18a62
Update baselines from update library test file, react.d.ts
Oct 20, 2016
5d66909
Treat JSXAttribute as declaration; Update .types and .symbol baselines
Oct 20, 2016
979f645
Use contextual type to find-all-reference and goto-definition for JSX…
Oct 21, 2016
df34e29
Add "(attribute)" to be use in quick-info display for JSXAttribute
Oct 21, 2016
c38f6c1
Update comment why we using contextual type in goto-definition when i…
Oct 22, 2016
5b454e6
Update incorrect baseline
Oct 24, 2016
33a5d98
Add tsx quick-info tests
Oct 24, 2016
f79f6d7
Cache testing lib files so we don't have to create source file everytime
Oct 24, 2016
96a4311
Add tests for stateless-function overload
Oct 22, 2016
8bac89e
Disallow excess property when check jsx attributes
Oct 24, 2016
cf83268
Merge branch 'wip-statelessOverload' of https://github.com/Microsoft/…
Oct 24, 2016
9a1ed32
Return the latest tried candidate when choosing overload
Oct 24, 2016
40e443c
Correct pick signature when there is a hyphenated name attribute
Oct 26, 2016
5eb5000
Update stateless function overload tests to include hyphenated name a…
Oct 26, 2016
dd08cc6
Add stateless function overload baselines
Oct 26, 2016
ab50bf3
Add hyphenated name jsx attributes and update baseline
Oct 26, 2016
ce4709c
Add contextual type in stateless function overload and baselines
Oct 26, 2016
8e4a699
Update baselines
Oct 26, 2016
c441f9f
Clean up using overload resolution for stateless function component
Oct 26, 2016
1c4f710
Add tests and update baselines for stateless function component with …
Oct 27, 2016
fd0c54c
Fix linting error
Oct 27, 2016
699db36
Add quickinfo tests for stateless function with type arguments
Oct 27, 2016
5fae439
Add support for react quick-info
Oct 31, 2016
e182674
Add quick info test cases for stateless function component
Nov 1, 2016
df7af98
Update baselines when ask for type of default JSX attribute (no initi…
Nov 1, 2016
40b1138
Add completion fourslash tests
Nov 1, 2016
116c878
Test case for property used in destructuring variable declaration
sheetalkamat Nov 2, 2016
13e8f7f
Mark property referenced in the destructuring as referenced
sheetalkamat Nov 2, 2016
ab75ea7
module resolution: prefer locally defined ambient modules, reuse reso…
vladima Nov 2, 2016
e8c3d62
Lock tslint version to 4.0.0-dev.0, because 4.0.0-dev.1 complains abo…
Nov 3, 2016
83abd04
Correct assignability for keyof types and type parameters
ahejlsberg Nov 3, 2016
4019265
Update tests
ahejlsberg Nov 3, 2016
d9b0b63
Accept new baselines
ahejlsberg Nov 3, 2016
6a5de5d
Fix linting errors
ahejlsberg Nov 3, 2016
9705791
Merge pull request #12021 from Microsoft/tslint_version
Nov 3, 2016
48f2b78
Merge branch 'master' into keyofAndConstraints
ahejlsberg Nov 3, 2016
702efd5
Merge pull request #12026 from Microsoft/keyofAndConstraints
ahejlsberg Nov 3, 2016
c6a5a56
Get attributes completion for JSX statelss function component
Nov 3, 2016
0027cee
Update Jsx completion tests to be more restrictive
Nov 3, 2016
7cb51d3
Add Jsx singature helps tests
Nov 3, 2016
fb6846d
Correctly display stateless function in signature help
Nov 3, 2016
cbec19a
Ensure transformFlags are correct before visiting a node.
rbuckton Nov 4, 2016
1c004bf
Port #12027, #11980 and #11932 to master (#12037)
zhengbli Nov 4, 2016
defc053
Merge pull request #12039 from Microsoft/fix12010
rbuckton Nov 4, 2016
4a90614
Merge pull request #11998 from Microsoft/unusedProperty
sheetalkamat Nov 4, 2016
30afb33
Add goto-definition tests for JSX and object literal
Nov 4, 2016
0d4c9fa
Handle goto-definition of stateless function component
Nov 4, 2016
9a25fa9
Update Jsx completion tests
Nov 4, 2016
e188191
Add JSX rename and find all references tests
Nov 4, 2016
98062a9
Merge branch 'object-spread' into wip-statelessOverload
Nov 4, 2016
126260b
Update get attributes symbol arrays and report an error when spreadin…
Nov 4, 2016
ed4fead
add missing bind calls to properly set parent on token nodes (#12057)
vladima Nov 5, 2016
c52be4a
Merge branch 'master' into wip-statelessOverload
Nov 7, 2016
12bb35a
Merge branch 'object-spread' into wip-statelessOverload
Nov 7, 2016
3f32fa1
Update baselines. Only allow objec type in spread (e.g no generic)
Nov 7, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
"travis-fold": "latest",
"ts-node": "latest",
"tsd": "latest",
"tslint": "next",
"tslint": "4.0.0-dev.0",
"typescript": "next"
},
"scripts": {
Expand Down
19 changes: 19 additions & 0 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1237,9 +1237,11 @@ namespace ts {
const postExpressionLabel = createBranchLabel();
bindCondition(node.condition, trueLabel, falseLabel);
currentFlow = finishFlowLabel(trueLabel);
bind(node.questionToken);
bind(node.whenTrue);
addAntecedent(postExpressionLabel, currentFlow);
currentFlow = finishFlowLabel(falseLabel);
bind(node.colonToken);
bind(node.whenFalse);
addAntecedent(postExpressionLabel, currentFlow);
currentFlow = finishFlowLabel(postExpressionLabel);
Expand Down Expand Up @@ -1297,6 +1299,7 @@ namespace ts {
case SyntaxKind.TypeLiteral:
case SyntaxKind.JSDocTypeLiteral:
case SyntaxKind.JSDocRecordType:
case SyntaxKind.JsxAttributes:
return ContainerFlags.IsContainer;

case SyntaxKind.InterfaceDeclaration:
Expand Down Expand Up @@ -1402,6 +1405,7 @@ namespace ts {
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.JSDocRecordType:
case SyntaxKind.JSDocTypeLiteral:
case SyntaxKind.JsxAttributes:
// Interface/Object-types always have their children added to the 'members' of
// their container. They are only accessible through an instance of their
// container, and are never in scope otherwise (even inside the body of the
Expand Down Expand Up @@ -1585,6 +1589,14 @@ namespace ts {
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object");
}

function bindJsxAttributes(node: JsxAttributes) {
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__jsxAttributes");
}

function bindJsxAttribute(node: JsxAttribute, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
}

function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) {
const symbol = createSymbol(symbolFlags, name);
addDeclarationToSymbol(symbol, node, symbolFlags);
Expand Down Expand Up @@ -1994,6 +2006,12 @@ namespace ts {
case SyntaxKind.ModuleDeclaration:
return bindModuleDeclaration(<ModuleDeclaration>node);

// Jsx-attributes
case SyntaxKind.JsxAttributes:
return bindJsxAttributes(<JsxAttributes>node);
case SyntaxKind.JsxAttribute:
return bindJsxAttribute(<JsxAttribute>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);

// Imports and exports
case SyntaxKind.ImportEqualsDeclaration:
case SyntaxKind.NamespaceImport:
Expand Down Expand Up @@ -3050,6 +3068,7 @@ namespace ts {
case SyntaxKind.JsxText:
case SyntaxKind.JsxClosingElement:
case SyntaxKind.JsxAttribute:
case SyntaxKind.JsxAttributes:
case SyntaxKind.JsxSpreadAttribute:
case SyntaxKind.JsxExpression:
// These nodes are Jsx syntax.
Expand Down
745 changes: 563 additions & 182 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,18 @@ namespace ts {
};
}

export function createCompilerDiagnosticFromMessageChain(chain: DiagnosticMessageChain): Diagnostic {
return {
file: undefined,
start: undefined,
length: undefined,

code: chain.code,
category: chain.category,
messageText: chain.next ? chain : chain.messageText
};
}

export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: any[]): DiagnosticMessageChain;
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage): DiagnosticMessageChain {
let text = getLocaleSpecificMessage(message);
Expand Down
12 changes: 12 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2893,6 +2893,14 @@
"category": "Error",
"code": 6143
},
"Module '{0}' was resolved as locally declared ambient module in file '{1}'.": {
"category": "Message",
"code": 6144
},
"Module '{0}' was resolved as ambient module declared in '{1}' since this file was not modified.": {
"category": "Message",
"code": 6145
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005
Expand Down Expand Up @@ -3154,5 +3162,9 @@
"Implement inherited abstract class": {
"category": "Message",
"code": 90007
},
"Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig": {
"category": "Error",
"code": 90009
}
}
18 changes: 15 additions & 3 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,8 @@ const _super = (function (geti, seti) {
return emitJsxClosingElement(<JsxClosingElement>node);
case SyntaxKind.JsxAttribute:
return emitJsxAttribute(<JsxAttribute>node);
case SyntaxKind.JsxAttributes:
return emitJsxAttributes(<JsxAttributes>node);
case SyntaxKind.JsxSpreadAttribute:
return emitJsxSpreadAttribute(<JsxSpreadAttribute>node);
case SyntaxKind.JsxExpression:
Expand Down Expand Up @@ -1969,15 +1971,21 @@ const _super = (function (geti, seti) {
write("<");
emitJsxTagName(node.tagName);
write(" ");
emitList(node, node.attributes, ListFormat.JsxElementAttributes);
// We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap
if (node.attributes.properties && node.attributes.properties.length > 0) {
emit(node.attributes);
}
write("/>");
}

function emitJsxOpeningElement(node: JsxOpeningElement) {
write("<");
emitJsxTagName(node.tagName);
writeIfAny(node.attributes, " ");
emitList(node, node.attributes, ListFormat.JsxElementAttributes);
writeIfAny(node.attributes.properties, " ");
// We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap
if (node.attributes.properties && node.attributes.properties.length > 0) {
emit(node.attributes);
}
write(">");
}

Expand All @@ -1991,6 +1999,10 @@ const _super = (function (geti, seti) {
write(">");
}

function emitJsxAttributes(node: JsxAttributes) {
emitList(node, node.properties, ListFormat.JsxElementAttributes);
}

function emitJsxAttribute(node: JsxAttribute) {
emit(node.name);
emitWithPrefix("=", node.initializer);
Expand Down
26 changes: 20 additions & 6 deletions src/compiler/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1237,28 +1237,28 @@ namespace ts {
return node;
}

export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) {
export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributes, location?: TextRange) {
const node = <JsxSelfClosingElement>createNode(SyntaxKind.JsxSelfClosingElement, location);
node.tagName = tagName;
node.attributes = createNodeArray(attributes);
node.attributes = attributes;
return node;
}

export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) {
export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributes) {
if (node.tagName !== tagName || node.attributes !== attributes) {
return updateNode(createJsxSelfClosingElement(tagName, attributes, node), node);
}
return node;
}

export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) {
export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributes, location?: TextRange) {
const node = <JsxOpeningElement>createNode(SyntaxKind.JsxOpeningElement, location);
node.tagName = tagName;
node.attributes = createNodeArray(attributes);
node.attributes = attributes;
return node;
}

export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) {
export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributes) {
if (node.tagName !== tagName || node.attributes !== attributes) {
return updateNode(createJsxOpeningElement(tagName, attributes, node), node);
}
Expand All @@ -1278,6 +1278,20 @@ namespace ts {
return node;
}

export function createJsxAttributes(properties: JsxAttributeLike[], location?: TextRange) {
const jsxAttributes = <JsxAttributes>createNode(SyntaxKind.JsxAttributes, location);
setEmitFlags(jsxAttributes, EmitFlags.NoSourceMap);
jsxAttributes.properties = createNodeArray(properties);
return jsxAttributes;
}

export function updateJsxAttributes(jsxAttributes: JsxAttributes, properties: JsxAttributeLike[]) {
if (jsxAttributes.properties !== properties) {
return updateNode(createJsxAttributes(properties, jsxAttributes), jsxAttributes);
}
return jsxAttributes;
}

export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression, location?: TextRange) {
const node = <JsxAttribute>createNode(SyntaxKind.JsxAttribute, location);
node.name = name;
Expand Down
9 changes: 6 additions & 3 deletions src/compiler/moduleNameResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
/// <reference path="diagnosticInformationMap.generated.ts" />

namespace ts {
function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
function trace(host: ModuleResolutionHost): void {

/* @internal */
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
export function trace(host: ModuleResolutionHost): void {
host.trace(formatMessage.apply(undefined, arguments));
}

function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleResolutionHost): boolean {
/* @internal */
export function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleResolutionHost): boolean {
return compilerOptions.traceResolution && host.trace !== undefined;
}

Expand Down
12 changes: 10 additions & 2 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,9 @@ namespace ts {
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxOpeningElement:
return visitNode(cbNode, (<JsxOpeningLikeElement>node).tagName) ||
visitNodes(cbNodes, (<JsxOpeningLikeElement>node).attributes);
visitNode(cbNode, (<JsxOpeningLikeElement>node).attributes);
case SyntaxKind.JsxAttributes:
return visitNodes(cbNodes, (<JsxAttributes>node).properties);
case SyntaxKind.JsxAttribute:
return visitNode(cbNode, (<JsxAttribute>node).name) ||
visitNode(cbNode, (<JsxAttribute>node).initializer);
Expand Down Expand Up @@ -3795,14 +3797,20 @@ namespace ts {
return result;
}

function parseJsxAttributes(): JsxAttributes {
const jsxAttributes = <JsxAttributes>createNode(SyntaxKind.JsxAttributes);
jsxAttributes.properties = parseList(ParsingContext.JsxAttributes, parseJsxAttribute);
return finishNode(jsxAttributes);
}

function parseJsxOpeningOrSelfClosingElement(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement {
const fullStart = scanner.getStartPos();

parseExpected(SyntaxKind.LessThanToken);

const tagName = parseJsxElementName();
const attributes = parseJsxAttributes();

const attributes = parseList(ParsingContext.JsxAttributes, parseJsxAttribute);
let node: JsxOpeningLikeElement;

if (token() === SyntaxKind.GreaterThanToken) {
Expand Down
Loading