Skip to content

Commit

Permalink
added jsx: "local" mode to support render systems like VueJS
Browse files Browse the repository at this point in the history
  • Loading branch information
notoriousbot committed Nov 5, 2016
1 parent 4a90614 commit 44ade7a
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 22 deletions.
31 changes: 16 additions & 15 deletions lib/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */

/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */

/// <reference path="../../src/server/types.d.ts" />
/// <reference types="node" />
declare namespace ts {
Expand Down Expand Up @@ -3509,6 +3509,7 @@ declare namespace ts.server.protocol {
type None = "None";
type Preserve = "Preserve";
type React = "React";
type Local = "Local";
}
type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React;
namespace ModuleKind {
Expand Down
17 changes: 17 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11346,6 +11346,23 @@ namespace ts {
}
}

// if JSX mode is local, check that createElement is in scope
if (compilerOptions.jsx === JsxEmit.Local) {
const createElementRefError = Diagnostics.Cannot_find_name_0;
const createElementFnName = "createElement";
const createElementSym = resolveName(node.tagName, createElementFnName, SymbolFlags.Value, createElementRefError, createElementFnName);
if (createElementSym) {
// Mark local symbol as referenced here because it might not have been marked
// if jsx emit was not simple as there wont be error being emitted
createElementSym.isReferenced = true;

// If createElement symbol is alias, mark it as refereced
if (createElementSym.flags & SymbolFlags.Alias && !isConstEnumOrConstEnumOnlyModule(resolveAlias(createElementSym))) {
markAliasSymbolAsReferenced(createElementSym);
}
}
}

const targetAttributesType = getJsxElementAttributesType(node);

const nameTable = createMap<boolean>();
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ namespace ts {
name: "jsx",
type: createMap({
"preserve": JsxEmit.Preserve,
"react": JsxEmit.React
"react": JsxEmit.React,
"local": JsxEmit.Local
}),
paramType: Diagnostics.KIND,
description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_or_react,
Expand Down
24 changes: 22 additions & 2 deletions src/compiler/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1628,7 +1628,19 @@ namespace ts {
return react;
}

export function createReactCreateElement(reactNamespace: string, tagName: Expression, props: Expression, children: Expression[], parentElement: JsxOpeningLikeElement, location: TextRange): LeftHandSideExpression {
function createSynthCreateElement(parent: JsxOpeningLikeElement) {
// To ensure the emit resolver can properly resolve the namespace, we need to
// treat this identifier as if it were a source tree node by clearing the `Synthesized`
// flag and setting a parent node.
const react = createIdentifier("createElement");
react.flags &= ~NodeFlags.Synthesized;
// Set the parent that is in parse tree
// this makes sure that parent chain is intact for checker to traverse complete scope tree
react.parent = getParseTreeNode(parent);
return react;
}

export function createReactCreateElement(reactNamespace: string, tagName: Expression, props: Expression, children: Expression[], parentElement: JsxOpeningLikeElement, location: TextRange, jsxEmit: JsxEmit): LeftHandSideExpression {
const argumentsList = [tagName];
if (props) {
argumentsList.push(props);
Expand All @@ -1650,12 +1662,20 @@ namespace ts {
}
}

if (jsxEmit === JsxEmit.Local) {
return createCall(
createSynthCreateElement(parentElement),
/*typeArguments*/ undefined,
argumentsList,
location);
}

return createCall(
createPropertyAccess(
createReactNamespace(reactNamespace, parentElement),
"createElement"
),
/*typeArguments*/ undefined,
/*typeArguments*/ undefined,
argumentsList,
location
);
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ namespace ts {

transformers.push(transformTypeScript);

if (jsx === JsxEmit.React) {
if (jsx === JsxEmit.React || jsx === JsxEmit.Local) {
transformers.push(transformJsx);
}

Expand Down
5 changes: 3 additions & 2 deletions src/compiler/transformers/jsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,15 @@ namespace ts {
objectProperties = singleOrUndefined(segments)
|| createAssignHelper(currentSourceFile.externalHelpersModuleName, segments);
}

const element = createReactCreateElement(
compilerOptions.reactNamespace,
tagName,
objectProperties,
filter(map(children, transformJsxChildToExpression), isDefined),
node,
location
location,
compilerOptions.jsx
);

if (isChild) {
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3131,7 +3131,8 @@ namespace ts {
export const enum JsxEmit {
None = 0,
Preserve = 1,
React = 2
React = 2,
Local = 3
}

export const enum NewLineKind {
Expand Down

0 comments on commit 44ade7a

Please sign in to comment.