Skip to content

Commit

Permalink
test(ivy): switch HelloWorld to ivy compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
mhevery committed Mar 18, 2018
1 parent f258ec6 commit f4f2494
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 27 deletions.
6 changes: 3 additions & 3 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ workspace(name = "angular")

http_archive(
name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.5.3.zip",
strip_prefix = "rules_nodejs-0.5.3",
sha256 = "17a5515f59777b00cb25dbc710017a14273f825029b2ec60e0969d28914870be",
url = "https://github.com/mhevery/rules_nodejs/archive/07c2cf1f04fa7b68220d730bc8df37ee9811b5e8.zip",
strip_prefix = "rules_nodejs-07c2cf1f04fa7b68220d730bc8df37ee9811b5e8",
sha256 = "7dbdec2d73a83fd0a34dbe3b459b810fd0b3e580152bc3fcd339784ad4dae988",
)

load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/render3/assert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ export function assertNotNull<T>(actual: T, msg: string) {
}
}

export function assertComponentType(actual: any) {
if (!actual.ngComponentDef) {
throwError(
'Type passed in is not ComponentType, it does not have \'ngComponentDef\' property.');
}
}

function throwError(msg: string): never {
throw new Error(`ASSERTION ERROR: ${msg}`);
}
12 changes: 9 additions & 3 deletions packages/core/src/render3/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

// We are temporarily importing the existing viewEngine from core so we can be sure we are
// correctly implementing its interfaces for backwards compatibility.
import {Type} from '../core';
import {Injector} from '../di/injector';
import {ComponentRef as viewEngine_ComponentRef} from '../linker/component_factory';

import {assertNotNull} from './assert';
import {assertNotNull, assertComponentType} from './assert';
import {queueLifecycleHooks} from './hooks';
import {CLEAN_PROMISE, _getComponentHostLElementNode, createLView, createTView, directiveCreate, enterView, getDirectiveInstance, getRootView, hostElement, initChangeDetectorIfExisting, leaveView, locateHostElement, scheduleTick, tick} from './instructions';
import {ComponentDef, ComponentType} from './interfaces/definition';
Expand All @@ -21,6 +22,7 @@ import {stringify} from './util';
import {createViewRef} from './view_ref';



/** Options that control how the component should be bootstrapped. */
export interface CreateComponentOptions {
/** Which renderer factory to use. */
Expand Down Expand Up @@ -111,9 +113,13 @@ export const NULL_INJECTOR: Injector = {
* @param options Optional parameters which control bootstrapping
*/
export function renderComponent<T>(
componentType: ComponentType<T>, opts: CreateComponentOptions = {}): T {
componentType: ComponentType<T>|
Type<T>/* Type as workaround for: Microsoft/TypeScript/issues/4881 */
,
opts: CreateComponentOptions = {}): T {
ngDevMode && assertComponentType(componentType);
const rendererFactory = opts.rendererFactory || domRendererFactory3;
const componentDef = componentType.ngComponentDef as ComponentDef<T>;
const componentDef = (componentType as ComponentType<T>).ngComponentDef as ComponentDef<T>;
if (componentDef.type != componentType) componentDef.type = componentType;
let component: T;
const hostNode = locateHostElement(rendererFactory, opts.host || componentDef.tag);
Expand Down
15 changes: 13 additions & 2 deletions packages/core/test/bundling/hello_world/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package(default_visibility = ["//visibility:public"])

load("//tools:defaults.bzl", "ts_library")
load("//tools:defaults.bzl", "ts_library", "ivy_ng_module")
load("//tools/symbol-extractor:index.bzl", "js_expected_symbol_test")
load("//packages/bazel/src:ng_rollup_bundle.bzl", "ng_rollup_bundle")
load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")

ts_library(
ivy_ng_module(
name = "hello_world",
srcs = ["index.ts"],
deps = [
Expand Down Expand Up @@ -54,3 +55,13 @@ js_expected_symbol_test(
src = ":bundle.min_debug.js",
golden = ":bundle.golden_symbols.json",
)

ts_devserver(
name = "devserver",
static_files = [
":bundle.min_debug.js",
":bundle.min.js",
"index.html",
],
deps = [],
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
{
"name": "EMPTY_RENDERER_TYPE_ID"
},
{
"name": "HelloWorld"
},
{
"name": "INeedToExistEvenThoughtIAmNotNeeded"
},
{
"name": "NG_HOST_SYMBOL"
},
Expand Down Expand Up @@ -74,6 +80,9 @@
{
"name": "defineComponent"
},
{
"name": "defineInjector"
},
{
"name": "detectChangesInternal"
},
Expand Down
31 changes: 31 additions & 0 deletions packages/core/test/bundling/hello_world/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!doctype html>

<html>
<head>
<title>Angular Hello World Example</title>
</head>
<body>
<!-- The Angular application will be bootstrapped into this element. -->
<hello-world></hello-world>

<!--
Script tag which bootstraps the application. Use `?debug` in URL to select
the debug version of the script.
There are two scripts sources: `bundle.min.js` and `bundle.min_debug.js` You can
switch between which bundle the browser loads to experiment with the application.
- `bundle.min.js`: Is what the site would serve to their users. It has gone
through rollup, build-optimizer, and uglify with tree shaking.
- `bundle.min_debug.js`: Is what the developer would like to see when debugging
the application. It has also done through full pipeline of rollup, build-optimizer,
and uglify, however special flags were passed to uglify to prevent inlining and
property renaming.
-->
<script>
document.write('<script src="' +
(document.location.search.endsWith('debug') ? '/bundle.min_debug.js' : '/bundle.min.js') +
'"></' + 'script>');
</script>
</body>
</html>
27 changes: 13 additions & 14 deletions packages/core/test/bundling/hello_world/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,21 @@
* found in the LICENSE file at https://angular.io/license
*/

import {ɵT as T, ɵdefineComponent as defineComponent, ɵi1 as i1, ɵrenderComponent as renderComponent, ɵt as t} from '@angular/core';
import {ɵrenderComponent as renderComponent, Component, NgModule} from '@angular/core';

class HelloWorld {
@Component({
selector: 'hello-world',
template: 'Hello {{name}}!'
})
export class HelloWorld {
name = 'World';

static ngComponentDef = defineComponent({
type: HelloWorld,
tag: 'hello-world',
factory: () => new HelloWorld(),
template: function HelloWorldTemplate(ctx: HelloWorld, cm: boolean) {
if (cm) {
T(0);
}
t(0, i1('Hello ', ctx.name, '!'));
}
});
}
//TODO(misko): Forgeting to export HellWorld and not having NgModule fails silently.

@NgModule({
declarations: [HelloWorld]
})
export class INeedToExistEvenThoughtIAmNotNeeded {}
//TODO(misko): Package should not be required to make this work.

renderComponent(HelloWorld);
29 changes: 24 additions & 5 deletions tools/symbol-extractor/symbol_extractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ export class SymbolExtractor {
static parse(path: string, contents: string): Symbol[] {
const symbols: Symbol[] = [];
const source: ts.SourceFile = ts.createSourceFile(path, contents, ts.ScriptTarget.Latest, true);
let fnDepth = 0;
let fnRecurseDepth = 0;
function visitor(child: ts.Node) {
// Left for easier debugging.
// console.log('>>>', ts.SyntaxKind[child.kind]);
switch (child.kind) {
case ts.SyntaxKind.FunctionExpression:
fnDepth++;
if (fnDepth <= 1) {
// Only go into function expression once for the outer closure.
fnRecurseDepth++;
if (fnRecurseDepth <= 1) {
ts.forEachChild(child, visitor);
}
break;
Expand All @@ -44,9 +45,12 @@ export class SymbolExtractor {
break;
case ts.SyntaxKind.VariableDeclaration:
const varDecl = child as ts.VariableDeclaration;
if (varDecl.initializer) {
if (varDecl.initializer && fnRecurseDepth !== 0) {
symbols.push({name: varDecl.name.getText()});
}
if (fnRecurseDepth == 0 && isStoringIIFE(child.parent as ts.VariableDeclarationList)) {
ts.forEachChild(child, visitor);
}
break;
case ts.SyntaxKind.FunctionDeclaration:
const funcDecl = child as ts.FunctionDeclaration;
Expand Down Expand Up @@ -114,3 +118,18 @@ function toSymbol(v: string | Symbol): Symbol {
function toName(symbol: Symbol): string {
return symbol.name;
}

/**
* Detects if VariableDeclarationList is format `var x = function(){}()`;
*
* Rollup produces this format when it wants to export symbols from a bundle.
* @param child
*/
function isStoringIIFE(child: ts.VariableDeclarationList): boolean {
if (child.declarations.length !== 1) return false;
const decl: ts.VariableDeclaration = child.declarations[0];
if (decl.initializer && decl.initializer.kind == ts.SyntaxKind.CallExpression) {
return true;
}
return false;
}
21 changes: 21 additions & 0 deletions tools/symbol-extractor/symbol_extractor_spec/iife_with_export.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var fooBar = function(exports) {
"use strict";
console.log("Hello, Alice in Wonderland");
var A = function() {
function A() {}
A.prototype.a = function() {
return document.a;
};
return A;
}();
console.error(new A().a());
exports.A = A;
return exports;
}({});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
"A"
]

0 comments on commit f4f2494

Please sign in to comment.