test: Add bundle symbol extractor tool (#22002)
This tool will be used for extracting symbols out of bundles so that we can assert that only whitelisted symbols are allowed. PR Close #22002
This commit is contained in:
parent
6435ecd3c6
commit
20a900b648
|
@ -1,6 +1,7 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//tools:defaults.bzl", "ts_library")
|
||||
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")
|
||||
|
||||
|
@ -31,7 +32,9 @@ ts_library(
|
|||
name = "test_lib",
|
||||
testonly = 1,
|
||||
srcs = ["domino_typings.d.ts"] + glob(["*_spec.ts"]),
|
||||
deps = ["//packages:types"],
|
||||
deps = [
|
||||
"//packages:types",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
|
@ -44,3 +47,9 @@ jasmine_node_test(
|
|||
],
|
||||
deps = [":test_lib"],
|
||||
)
|
||||
|
||||
js_expected_symbol_test(
|
||||
name = "symbol_test",
|
||||
src = ":bundle.min_debug.js",
|
||||
golden = ":bundle.golden_symbols.json",
|
||||
)
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
[
|
||||
{
|
||||
"name": "EMPTY$1"
|
||||
},
|
||||
{
|
||||
"name": "NO_CHANGE"
|
||||
},
|
||||
{
|
||||
"name": "Symbol$1"
|
||||
},
|
||||
{
|
||||
"name": "__global$1"
|
||||
},
|
||||
{
|
||||
"name": "__self$1"
|
||||
},
|
||||
{
|
||||
"name": "__window$1"
|
||||
},
|
||||
{
|
||||
"name": "_renderCompCount"
|
||||
},
|
||||
{
|
||||
"name": "_root"
|
||||
},
|
||||
{
|
||||
"name": "canInsertNativeNode"
|
||||
},
|
||||
{
|
||||
"name": "createLNode"
|
||||
},
|
||||
{
|
||||
"name": "createLView"
|
||||
},
|
||||
{
|
||||
"name": "domRendererFactory3"
|
||||
},
|
||||
{
|
||||
"name": "enterView"
|
||||
},
|
||||
{
|
||||
"name": "executeHooks"
|
||||
},
|
||||
{
|
||||
"name": "findFirstRNode"
|
||||
},
|
||||
{
|
||||
"name": "getDirectiveInstance"
|
||||
},
|
||||
{
|
||||
"name": "getNextLNodeWithProjection"
|
||||
},
|
||||
{
|
||||
"name": "getNextOrParentSiblingNode"
|
||||
},
|
||||
{
|
||||
"name": "invertObject"
|
||||
},
|
||||
{
|
||||
"name": "isProceduralRenderer"
|
||||
},
|
||||
{
|
||||
"name": "leaveView"
|
||||
},
|
||||
{
|
||||
"name": "locateHostElement"
|
||||
},
|
||||
{
|
||||
"name": "noop$2"
|
||||
},
|
||||
{
|
||||
"name": "refreshDynamicChildren"
|
||||
},
|
||||
{
|
||||
"name": "renderComponentOrTemplate"
|
||||
},
|
||||
{
|
||||
"name": "renderEmbeddedTemplate"
|
||||
},
|
||||
{
|
||||
"name": "stringify$1"
|
||||
}
|
||||
]
|
|
@ -18,10 +18,8 @@ import * as domino from 'domino';
|
|||
|
||||
describe('treeshaking with uglify', () => {
|
||||
let content: string;
|
||||
beforeAll(() => {
|
||||
content = fs.readFileSync(
|
||||
path.join(process.env['TEST_SRCDIR'], PACKAGE, 'bundle.min_debug.js'), UTF8);
|
||||
});
|
||||
const contentPath = require.resolve(path.join(PACKAGE, 'bundle.min_debug.js'));
|
||||
beforeAll(() => { content = fs.readFileSync(contentPath, UTF8); });
|
||||
|
||||
it('should drop unused TypeScript helpers',
|
||||
() => { expect(content).not.toContain('__asyncGenerator'); });
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//tools:defaults.bzl", "ts_library")
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test")
|
||||
|
||||
ts_library(
|
||||
name = "lib",
|
||||
testonly = 1,
|
||||
srcs = glob(
|
||||
["**/*.ts"],
|
||||
exclude = [
|
||||
"**/*_spec.ts",
|
||||
"**/*_spec",
|
||||
],
|
||||
),
|
||||
deps = [
|
||||
"//packages:types",
|
||||
],
|
||||
)
|
||||
|
||||
ts_library(
|
||||
name = "test_lib",
|
||||
testonly = 1,
|
||||
srcs = glob(
|
||||
["**/*_spec.ts"],
|
||||
exclude = ["symbol_extractor_spec/**"],
|
||||
),
|
||||
deps = [
|
||||
":lib",
|
||||
"//packages:types",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "test",
|
||||
data = glob(["symbol_extractor_spec/**"]),
|
||||
deps = [
|
||||
":test_lib",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import {SymbolExtractor} from './symbol_extractor';
|
||||
|
||||
// These keys are arbitrary and local to this test.
|
||||
const update_var = 'UPDATE_GOLDEN';
|
||||
const update_val = 1;
|
||||
|
||||
if (require.main === module) {
|
||||
const doUpdate = process.env[update_var] == update_val;
|
||||
const args = process.argv.slice(2) as[string, string];
|
||||
process.exitCode = main(args, doUpdate) ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* CLI main method.
|
||||
*
|
||||
* ```
|
||||
* cli javascriptFilePath.js goldenFilePath.json
|
||||
* ```
|
||||
*/
|
||||
function main(argv: [string, string], doUpdate: boolean): boolean {
|
||||
const javascriptFilePath = require.resolve(argv[0]);
|
||||
const goldenFilePath = require.resolve(argv[1]);
|
||||
|
||||
const javascriptContent = fs.readFileSync(javascriptFilePath).toString();
|
||||
const goldenContent = fs.readFileSync(goldenFilePath).toString();
|
||||
|
||||
const symbolExtractor = new SymbolExtractor(javascriptFilePath, javascriptContent);
|
||||
|
||||
let passed: boolean = false;
|
||||
if (doUpdate) {
|
||||
fs.writeFileSync(goldenFilePath, JSON.stringify(symbolExtractor.actual, undefined, 2));
|
||||
console.error('Updated gold file:', goldenFilePath);
|
||||
passed = true;
|
||||
} else {
|
||||
passed = symbolExtractor.compareAndPrintError(goldenFilePath, goldenContent);
|
||||
if (!passed) {
|
||||
console.error(`TEST FAILED!`);
|
||||
console.error(` To update the golden file run: `);
|
||||
console.error(
|
||||
` bazel run --define ${update_var}=${update_val} ${process.env['BAZEL_TARGET']}`);
|
||||
}
|
||||
}
|
||||
return passed;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
# 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
|
||||
|
||||
"""This test verifies that a set of top level symbols from a javascript file match a gold file.
|
||||
"""
|
||||
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_test")
|
||||
|
||||
def js_expected_symbol_test(name, src, golden, **kwargs):
|
||||
all_data = [src, golden]
|
||||
all_data += [Label("//tools/symbol-extractor:lib")]
|
||||
entry_point = "angular/tools/symbol-extractor/cli.js"
|
||||
|
||||
nodejs_test(
|
||||
name = name,
|
||||
data = all_data,
|
||||
entry_point = entry_point,
|
||||
templated_args = ["$(location %s)" % src, "$(location %s)" % golden],
|
||||
**kwargs
|
||||
)
|
|
@ -0,0 +1,116 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
|
||||
export interface Symbol { name: string; }
|
||||
|
||||
export class SymbolExtractor {
|
||||
public actual: Symbol[];
|
||||
|
||||
static symbolSort(a: Symbol, b: Symbol): number {
|
||||
return a.name == b.name ? 0 : a.name < b.name ? -1 : 1;
|
||||
}
|
||||
|
||||
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;
|
||||
function visitor(child: ts.Node) {
|
||||
switch (child.kind) {
|
||||
case ts.SyntaxKind.FunctionExpression:
|
||||
fnDepth++;
|
||||
if (fnDepth <= 1) {
|
||||
// Only go into function expression once for the outer closure.
|
||||
ts.forEachChild(child, visitor);
|
||||
}
|
||||
break;
|
||||
case ts.SyntaxKind.SourceFile:
|
||||
case ts.SyntaxKind.VariableStatement:
|
||||
case ts.SyntaxKind.VariableDeclarationList:
|
||||
case ts.SyntaxKind.ExpressionStatement:
|
||||
case ts.SyntaxKind.CallExpression:
|
||||
case ts.SyntaxKind.ParenthesizedExpression:
|
||||
case ts.SyntaxKind.Block:
|
||||
case ts.SyntaxKind.PrefixUnaryExpression:
|
||||
ts.forEachChild(child, visitor);
|
||||
break;
|
||||
case ts.SyntaxKind.VariableDeclaration:
|
||||
const varDecl = child as ts.VariableDeclaration;
|
||||
if (varDecl.initializer) {
|
||||
symbols.push({name: varDecl.name.getText()});
|
||||
}
|
||||
break;
|
||||
case ts.SyntaxKind.FunctionDeclaration:
|
||||
const funcDecl = child as ts.FunctionDeclaration;
|
||||
funcDecl.name && symbols.push({name: funcDecl.name.getText()});
|
||||
break;
|
||||
default:
|
||||
// Left for easier debugging.
|
||||
// console.log('###', ts.SyntaxKind[child.kind], child.getText());
|
||||
}
|
||||
if (symbols.length && symbols[symbols.length - 1].name == 'type') {
|
||||
debugger;
|
||||
}
|
||||
}
|
||||
visitor(source);
|
||||
symbols.sort(SymbolExtractor.symbolSort);
|
||||
return symbols;
|
||||
}
|
||||
|
||||
static diff(actual: Symbol[], expected: string|((Symbol | string)[])): {[name: string]: string} {
|
||||
if (typeof expected == 'string') {
|
||||
expected = JSON.parse(expected);
|
||||
}
|
||||
const diff: {[name: string]: ('missing' | 'extra')} = {};
|
||||
(expected as(Symbol | string)[]).forEach((nameOrSymbol) => {
|
||||
diff[typeof nameOrSymbol == 'string' ? nameOrSymbol : nameOrSymbol.name] = 'missing';
|
||||
});
|
||||
|
||||
actual.forEach((s) => {
|
||||
if (diff[s.name] === 'missing') {
|
||||
delete diff[s.name];
|
||||
} else {
|
||||
diff[s.name] = 'extra';
|
||||
}
|
||||
});
|
||||
return diff;
|
||||
}
|
||||
|
||||
constructor(private path: string, private contents: string) {
|
||||
this.actual = SymbolExtractor.parse(path, contents);
|
||||
}
|
||||
|
||||
expect(expectedSymbols: (string|Symbol)[]) {
|
||||
expect(SymbolExtractor.diff(this.actual, expectedSymbols)).toEqual({});
|
||||
}
|
||||
|
||||
compareAndPrintError(goldenFilePath: string, expected: string|((Symbol | string)[])): boolean {
|
||||
let passed = true;
|
||||
const diff = SymbolExtractor.diff(this.actual, expected);
|
||||
Object.keys(diff).forEach((key) => {
|
||||
if (passed) {
|
||||
console.error(`Expected symbols in '${this.path}' did not match gold file.`);
|
||||
passed = false;
|
||||
}
|
||||
console.error(` Symbol: ${key} => ${diff[key]}`);
|
||||
});
|
||||
|
||||
return passed;
|
||||
}
|
||||
}
|
||||
|
||||
function toSymbol(v: string | Symbol): Symbol {
|
||||
return typeof v == 'string' ? {'name': v} : v as Symbol;
|
||||
}
|
||||
|
||||
function toName(symbol: Symbol): string {
|
||||
return symbol.name;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {Symbol, SymbolExtractor} from './symbol_extractor';
|
||||
|
||||
describe('scenarios', () => {
|
||||
const symbolExtractorSpecDir = path.dirname(
|
||||
require.resolve('angular/tools/symbol-extractor/symbol_extractor_spec/empty.json'));
|
||||
const scenarioFiles = fs.readdirSync(symbolExtractorSpecDir);
|
||||
for (let i = 0; i < scenarioFiles.length; i = i + 2) {
|
||||
let jsFile = scenarioFiles[i];
|
||||
let jsonFile = scenarioFiles[i + 1];
|
||||
let testName = jsFile.substring(0, jsFile.lastIndexOf('.'));
|
||||
if (!jsFile.endsWith('.js')) throw new Error('Expected: .js file found: ' + jsFile);
|
||||
if (!jsonFile.endsWith('.json')) throw new Error('Expected: .json file found: ' + jsonFile);
|
||||
|
||||
// Left here so that it is easy to debug single test.
|
||||
// if (testName !== 'hello_world_min_debug') continue;
|
||||
|
||||
it(testName, () => {
|
||||
const jsFileContent = fs.readFileSync(path.join(symbolExtractorSpecDir, jsFile)).toString();
|
||||
const jsonFileContent =
|
||||
fs.readFileSync(path.join(symbolExtractorSpecDir, jsonFile)).toString();
|
||||
const symbols = SymbolExtractor.parse(testName, jsFileContent);
|
||||
const diff = SymbolExtractor.diff(symbols, jsonFileContent);
|
||||
expect(diff).toEqual({});
|
||||
});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
!function() {
|
||||
function A() {
|
||||
function ignoreA() {}
|
||||
}
|
||||
function B() { let ignoreB = {}; }
|
||||
!function() { let ignoreC = {}; };
|
||||
}();
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"A",
|
||||
"B"
|
||||
]
|
|
@ -0,0 +1,9 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
export let __empty__;
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1,9 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
(function() {})();
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1,675 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
!function() {
|
||||
'use strict';
|
||||
/**
|
||||
*@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
|
||||
*/
|
||||
/**
|
||||
*@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 ChangeDetectionStrategy, ChangeDetectorStatus, ViewEncapsulation;
|
||||
Object;
|
||||
ChangeDetectionStrategy || (ChangeDetectionStrategy = {});
|
||||
ChangeDetectorStatus || (ChangeDetectorStatus = {});
|
||||
/**
|
||||
* @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
|
||||
*/ Object;
|
||||
ViewEncapsulation || (ViewEncapsulation = {});
|
||||
/**
|
||||
*@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
|
||||
*/
|
||||
/**
|
||||
* @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
|
||||
*/ 'undefined' != typeof window &&
|
||||
window,
|
||||
'undefined' != typeof self && 'undefined' != typeof WorkerGlobalScope &&
|
||||
self instanceof WorkerGlobalScope && self,
|
||||
'undefined' != typeof global && global;
|
||||
/**
|
||||
*@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
|
||||
*/
|
||||
String;
|
||||
/**
|
||||
*@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
|
||||
*/
|
||||
Function;
|
||||
var __window$1 = 'undefined' != typeof window && window, __self$1 = 'undefined' != typeof self &&
|
||||
'undefined' != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope && self,
|
||||
__global$1 = 'undefined' != typeof global && global,
|
||||
_root = __window$1 || __global$1 || __self$1;
|
||||
!function() {
|
||||
if (!_root) throw new Error('RxJS could not find any global context (window, self, global)');
|
||||
}();
|
||||
Array;
|
||||
!function() { Object.setPrototypeOf || Array; }();
|
||||
Error;
|
||||
var RendererStyleFlags2, Symbol$1 = _root.Symbol;
|
||||
'function' == typeof Symbol$1 && 'function' == typeof Symbol$1.for &&
|
||||
Symbol$1.for ('rxSubscriber'),
|
||||
function() { Object.setPrototypeOf || Array; }();
|
||||
!function(context) {
|
||||
var $$observable, Symbol = _root.Symbol;
|
||||
if ('function' == typeof Symbol)
|
||||
if (Symbol.observable)
|
||||
$$observable = Symbol.observable;
|
||||
else {
|
||||
$$observable = Symbol('observable');
|
||||
Symbol.observable = $$observable;
|
||||
}
|
||||
else
|
||||
$$observable = '@@observable';
|
||||
}();
|
||||
(function() { Object.setPrototypeOf || Array; })(),
|
||||
function() { Object.setPrototypeOf || Array; }();
|
||||
!function() { Object.setPrototypeOf || Array; }();
|
||||
(function(root) {
|
||||
var Symbol = root.Symbol;
|
||||
if ('function' == typeof Symbol) {
|
||||
Symbol.iterator || (Symbol.iterator = Symbol('iterator polyfill'));
|
||||
return Symbol.iterator;
|
||||
}
|
||||
var Set_1 = root.Set;
|
||||
if (Set_1 && 'function' == typeof new Set_1()['@@iterator']) return '@@iterator';
|
||||
var Map_1 = root.Map;
|
||||
if (Map_1)
|
||||
for (var keys = Object.getOwnPropertyNames(Map_1.prototype), i = 0; i < keys.length; ++i) {
|
||||
var key = keys[i];
|
||||
if ('entries' !== key && 'size' !== key && Map_1.prototype[key] === Map_1.prototype.entries)
|
||||
return key;
|
||||
}
|
||||
})(_root),
|
||||
function() { Object.setPrototypeOf || Array; }();
|
||||
(function() { Object.setPrototypeOf || Array; })(),
|
||||
function() { Object.setPrototypeOf || Array; }();
|
||||
!function() { Object.setPrototypeOf || Array; }();
|
||||
Error, function() { Object.setPrototypeOf || Array; }(), function() {
|
||||
Object.setPrototypeOf || Array;
|
||||
}(), function() { Object.setPrototypeOf || Array; }();
|
||||
!function() { Object.setPrototypeOf || Array; }();
|
||||
Object;
|
||||
RendererStyleFlags2 || (RendererStyleFlags2 = {});
|
||||
var RendererStyleFlags3, _renderCompCount = 0;
|
||||
function executeHooks(data, allHooks, checkHooks, creationMode) {
|
||||
var hooksToCall = creationMode ? allHooks : checkHooks;
|
||||
null != hooksToCall &&
|
||||
function(data, arr) {
|
||||
for (var i = 0; i < arr.length; i += 2) arr[1 | i].call(data[arr[i]]);
|
||||
}
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
/**
|
||||
* @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
|
||||
*/ (data, hooksToCall);
|
||||
}
|
||||
RendererStyleFlags3 || (RendererStyleFlags3 = {});
|
||||
var domRendererFactory3 = {
|
||||
createRenderer: function(hostElement, rendererType) { return document; }
|
||||
};
|
||||
/**
|
||||
*@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
|
||||
*/
|
||||
/**
|
||||
* @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
|
||||
*/ function
|
||||
getNextLNodeWithProjection(node) {
|
||||
var pNextOrParent = node.pNextOrParent;
|
||||
return pNextOrParent ? 1 == (3 & pNextOrParent.flags) ? null : pNextOrParent : node.next;
|
||||
}
|
||||
function getNextOrParentSiblingNode(initialNode, rootNode) {
|
||||
for (var node = initialNode, nextNode = getNextLNodeWithProjection(node); node && !nextNode;) {
|
||||
if ((node = node.pNextOrParent || node.parent) === rootNode) return null;
|
||||
nextNode = node && getNextLNodeWithProjection(node);
|
||||
}
|
||||
return nextNode;
|
||||
}
|
||||
function findFirstRNode(rootNode) {
|
||||
for (var node = rootNode; node;) {
|
||||
var type = 3 & node.flags, nextNode = null;
|
||||
if (3 === type) return node.native;
|
||||
if (0 === type) {
|
||||
var childContainerData = node.data;
|
||||
nextNode = childContainerData.views.length ? childContainerData.views[0].child : null;
|
||||
} else
|
||||
nextNode = 1 === type ? node.data.head : node.child;
|
||||
node = null === nextNode ? getNextOrParentSiblingNode(node, rootNode) : nextNode;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function canInsertNativeNode(parent, view) {
|
||||
return 3 == (3 & parent.flags) && (parent.view !== view || null === parent.data);
|
||||
}
|
||||
function stringify$1(value) {
|
||||
return 'function' == typeof value ?
|
||||
value.name || value :
|
||||
'string' == typeof value ? value : null == value ? '' : '' + value;
|
||||
}
|
||||
/**
|
||||
*@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 renderer, rendererFactory, previousOrParentNode, isParent, tData, currentView, currentQueries,
|
||||
creationMode, data, bindingIndex;
|
||||
currentView = createLView(null, null, createTView());
|
||||
function enterView(newView, host) {
|
||||
var oldView = currentView;
|
||||
data = newView.data;
|
||||
bindingIndex = newView.bindingStartIndex || 0;
|
||||
tData = newView.tView.data;
|
||||
creationMode = newView.creationMode;
|
||||
renderer = newView.renderer;
|
||||
if (null != host) {
|
||||
previousOrParentNode = host;
|
||||
isParent = !0;
|
||||
}
|
||||
currentView = newView;
|
||||
currentQueries = newView.queries;
|
||||
return oldView;
|
||||
}
|
||||
function leaveView(newView) {
|
||||
executeHooks(
|
||||
currentView.data, currentView.tView.viewHooks, currentView.tView.viewCheckHooks,
|
||||
creationMode);
|
||||
currentView.creationMode = !1;
|
||||
currentView.lifecycleStage = 1;
|
||||
currentView.tView.firstTemplatePass = !1;
|
||||
enterView(newView, null);
|
||||
}
|
||||
function createLView(viewId, renderer, tView, template, context) {
|
||||
void 0 === template && (template = null);
|
||||
void 0 === context && (context = null);
|
||||
return {
|
||||
parent: currentView,
|
||||
id: viewId,
|
||||
node: null,
|
||||
data: [],
|
||||
tView: tView,
|
||||
cleanup: null,
|
||||
renderer: renderer,
|
||||
child: null,
|
||||
tail: null,
|
||||
next: null,
|
||||
bindingStartIndex: null,
|
||||
creationMode: !0,
|
||||
template: template,
|
||||
context: context,
|
||||
dynamicViewCount: 0,
|
||||
lifecycleStage: 1,
|
||||
queries: null
|
||||
};
|
||||
}
|
||||
function createLNode(index, type, native, state) {
|
||||
var parent =
|
||||
isParent ? previousOrParentNode : previousOrParentNode && previousOrParentNode.parent,
|
||||
queries =
|
||||
(isParent ? currentQueries : previousOrParentNode && previousOrParentNode.queries) ||
|
||||
parent && parent.queries && parent.queries.child(),
|
||||
isState = null != state, node = {
|
||||
flags: type,
|
||||
native: native,
|
||||
view: currentView,
|
||||
parent: parent,
|
||||
child: null,
|
||||
next: null,
|
||||
nodeInjector: parent ? parent.nodeInjector : null,
|
||||
data: isState ? state : null,
|
||||
queries: queries,
|
||||
tNode: null,
|
||||
pNextOrParent: null
|
||||
};
|
||||
2 == (2 & type) && isState && (state.node = node);
|
||||
if (null != index) {
|
||||
data[index] = node;
|
||||
index >= tData.length ? tData[index] = null : node.tNode = tData[index];
|
||||
if (isParent) {
|
||||
currentQueries = null;
|
||||
previousOrParentNode.view !== currentView && 2 != (3 & previousOrParentNode.flags) ||
|
||||
(previousOrParentNode.child = node);
|
||||
} else
|
||||
previousOrParentNode && (previousOrParentNode.next = node);
|
||||
}
|
||||
previousOrParentNode = node;
|
||||
isParent = !0;
|
||||
return node;
|
||||
}
|
||||
function renderEmbeddedTemplate(viewNode, template, context, renderer) {
|
||||
var _isParent = isParent, _previousOrParentNode = previousOrParentNode;
|
||||
try {
|
||||
isParent = !0;
|
||||
previousOrParentNode = null;
|
||||
var cm = !1;
|
||||
if (null == viewNode) {
|
||||
viewNode =
|
||||
createLNode(null, 2, null, createLView(-1, renderer, createTView(), template, context));
|
||||
cm = !0;
|
||||
}
|
||||
enterView(viewNode.data, viewNode);
|
||||
template(context, cm);
|
||||
} finally {
|
||||
refreshDynamicChildren();
|
||||
leaveView(currentView.parent);
|
||||
isParent = _isParent;
|
||||
previousOrParentNode = _previousOrParentNode;
|
||||
}
|
||||
return viewNode;
|
||||
}
|
||||
function renderComponentOrTemplate(node, hostView, componentOrContext, template) {
|
||||
var oldView = enterView(hostView, node);
|
||||
try {
|
||||
rendererFactory.begin && rendererFactory.begin();
|
||||
template ? template(componentOrContext, creationMode) : function(
|
||||
directiveIndex, elementIndex) {
|
||||
!function(currentView, tView, creationMode) {
|
||||
if (1 === currentView.lifecycleStage) {
|
||||
executeHooks(currentView.data, tView.initHooks, tView.checkHooks, creationMode);
|
||||
currentView.lifecycleStage = 2;
|
||||
}
|
||||
}(currentView, currentView.tView, creationMode);
|
||||
!function(currentView, tView, creationMode) {
|
||||
if (currentView.lifecycleStage < 3) {
|
||||
executeHooks(
|
||||
currentView.data, tView.contentHooks, tView.contentCheckHooks, creationMode);
|
||||
currentView.lifecycleStage = 3;
|
||||
}
|
||||
}(currentView, currentView.tView, creationMode);
|
||||
var template = tData[1].template;
|
||||
if (null != template) {
|
||||
var element = data[0], directive = getDirectiveInstance(data[1]),
|
||||
oldView = enterView(element.data, element);
|
||||
try {
|
||||
template(directive, creationMode);
|
||||
} finally {
|
||||
refreshDynamicChildren();
|
||||
leaveView(oldView);
|
||||
}
|
||||
}
|
||||
}();
|
||||
} finally {
|
||||
rendererFactory.end && rendererFactory.end();
|
||||
leaveView(oldView);
|
||||
}
|
||||
}
|
||||
function createTView() {
|
||||
return {
|
||||
data: [],
|
||||
firstTemplatePass: !0,
|
||||
initHooks: null,
|
||||
checkHooks: null,
|
||||
contentHooks: null,
|
||||
contentCheckHooks: null,
|
||||
viewHooks: null,
|
||||
viewCheckHooks: null,
|
||||
destroyHooks: null,
|
||||
objectLiterals: null
|
||||
};
|
||||
}
|
||||
function locateHostElement(factory, elementOrSelector) {
|
||||
rendererFactory = factory;
|
||||
var defaultRenderer = factory.createRenderer(null, null);
|
||||
return 'string' == typeof elementOrSelector ?
|
||||
defaultRenderer.selectRootElement ? defaultRenderer.selectRootElement(elementOrSelector) :
|
||||
defaultRenderer.querySelector(elementOrSelector) :
|
||||
elementOrSelector;
|
||||
}
|
||||
function refreshDynamicChildren() {
|
||||
for (var current = currentView.child; null !== current; current = current.next)
|
||||
if (0 !== current.dynamicViewCount && current.views)
|
||||
for (var container_1 = current, i = 0; i < container_1.views.length; i++) {
|
||||
var view = container_1.views[i];
|
||||
renderEmbeddedTemplate(view, view.data.template, view.data.context, renderer);
|
||||
}
|
||||
}
|
||||
var NO_CHANGE = {};
|
||||
function getDirectiveInstance(instanceOrArray) {
|
||||
return Array.isArray(instanceOrArray) ? instanceOrArray[0] : instanceOrArray;
|
||||
}
|
||||
var EMPTY$1 = {};
|
||||
function noop$2() {}
|
||||
function invertObject(obj) {
|
||||
if (null == obj) return EMPTY$1;
|
||||
var newObj = {};
|
||||
for (var minifiedKey in obj) newObj[obj[minifiedKey]] = minifiedKey;
|
||||
return newObj;
|
||||
}
|
||||
/**
|
||||
*@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
|
||||
*/
|
||||
/**
|
||||
*@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
|
||||
*/
|
||||
/**
|
||||
*@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
|
||||
*/
|
||||
/**
|
||||
*@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
|
||||
*/
|
||||
/**
|
||||
* @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
|
||||
*/ Object;
|
||||
/**
|
||||
* @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
|
||||
*/ !
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
function(componentType, opts) {
|
||||
void 0 === opts && (opts = {});
|
||||
var component, rendererFactory = opts.rendererFactory || domRendererFactory3,
|
||||
componentDef = componentType.ngComponentDef;
|
||||
componentDef.type != componentType && (componentDef.type = componentType);
|
||||
var hostNode = locateHostElement(rendererFactory, opts.host || componentDef.tag),
|
||||
oldView = enterView(
|
||||
createLView(
|
||||
-1, rendererFactory.createRenderer(hostNode, componentDef.rendererType),
|
||||
createTView()),
|
||||
null);
|
||||
try {
|
||||
!function(rNode, def) {
|
||||
!function() {
|
||||
isParent = !1;
|
||||
previousOrParentNode = null;
|
||||
}();
|
||||
createLNode(0, 3, rNode, createLView(-1, renderer, function(template) {
|
||||
return template.ngPrivateData || (template.ngPrivateData = createTView());
|
||||
}(def.template)));
|
||||
}(hostNode, componentDef);
|
||||
component = getDirectiveInstance(function(index, directive, directiveDef, queryName) {
|
||||
var instance, flags = previousOrParentNode.flags;
|
||||
0 == (4092 & flags) ? flags = 4100 | 3 & flags : flags += 4;
|
||||
previousOrParentNode.flags = flags;
|
||||
Object.defineProperty(
|
||||
directive, '__ngHostLNode__', {enumerable: !1, value: previousOrParentNode});
|
||||
data[1] = instance = directive;
|
||||
if (1 >= tData.length) {
|
||||
tData[1] = directiveDef;
|
||||
}
|
||||
var diPublic = directiveDef.diPublic;
|
||||
diPublic && diPublic(directiveDef);
|
||||
var tNode = previousOrParentNode.tNode;
|
||||
tNode && tNode.attrs && function(instance, inputs, tNode) {
|
||||
var directiveIndex = ((4092 & previousOrParentNode.flags) >> 2) - 1,
|
||||
initialInputData = tNode.initialInputs;
|
||||
(void 0 === initialInputData || directiveIndex >= initialInputData.length) &&
|
||||
(initialInputData = function(directiveIndex, inputs, tNode) {
|
||||
var initialInputData = tNode.initialInputs || (tNode.initialInputs = []);
|
||||
initialInputData[directiveIndex] = null;
|
||||
for (var attrs = tNode.attrs, i = 0; i < attrs.length; i += 2) {
|
||||
var minifiedInputName = inputs[attrs[i]];
|
||||
void 0 !== minifiedInputName &&
|
||||
(initialInputData[directiveIndex] || (initialInputData[directiveIndex] = [
|
||||
])).push(minifiedInputName, attrs[1 | i]);
|
||||
}
|
||||
return initialInputData;
|
||||
}(directiveIndex, directiveDef.inputs, tNode));
|
||||
var initialInputs = initialInputData[directiveIndex];
|
||||
if (initialInputs)
|
||||
for (var i = 0; i < initialInputs.length; i += 2)
|
||||
instance[initialInputs[i]] = initialInputs[1 | i];
|
||||
}(instance, 0, tNode);
|
||||
!
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
function(index, onInit, doCheck, tView) {
|
||||
if (!0 === tView.firstTemplatePass) {
|
||||
null != onInit && (tView.initHooks || (tView.initHooks = [])).push(1, onInit);
|
||||
if (null != doCheck) {
|
||||
(tView.initHooks || (tView.initHooks = [])).push(1, doCheck);
|
||||
(tView.checkHooks || (tView.checkHooks = [])).push(1, doCheck);
|
||||
}
|
||||
}
|
||||
}(0, directiveDef.onInit, directiveDef.doCheck, currentView.tView);
|
||||
return instance;
|
||||
}(0, componentDef.n(), componentDef));
|
||||
} finally {
|
||||
leaveView(oldView);
|
||||
}
|
||||
opts.features &&
|
||||
opts.features.forEach(function(feature) { return feature(component, componentDef); });
|
||||
!function(component) {
|
||||
var hostNode = component.__ngHostLNode__;
|
||||
renderComponentOrTemplate(hostNode, hostNode.view, component);
|
||||
}
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
/**
|
||||
* @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
|
||||
*/ (component);
|
||||
}(function() {
|
||||
function HelloWorld() { this.name = 'World'; }
|
||||
HelloWorld.ngComponentDef = function(componentDefinition) {
|
||||
var type = componentDefinition.type, def = {
|
||||
type: type,
|
||||
diPublic: null,
|
||||
n: componentDefinition.factory,
|
||||
tag: componentDefinition.tag || null,
|
||||
template: componentDefinition.template || null,
|
||||
h: componentDefinition.hostBindings || noop$2,
|
||||
inputs: invertObject(componentDefinition.inputs),
|
||||
outputs: invertObject(componentDefinition.outputs),
|
||||
methods: invertObject(componentDefinition.methods),
|
||||
rendererType: function(type) {
|
||||
if (type && '$$undefined' === type.id) {
|
||||
var isFilled =
|
||||
null != type.encapsulation && type.encapsulation !== ViewEncapsulation.None ||
|
||||
type.styles.length || Object.keys(type.data).length;
|
||||
type.id = isFilled ? 'c' + _renderCompCount++ : '$$empty';
|
||||
}
|
||||
type && '$$empty' === type.id && (type = null);
|
||||
return type || null;
|
||||
}(componentDefinition.rendererType) ||
|
||||
null,
|
||||
exportAs: componentDefinition.exportAs,
|
||||
onInit: type.prototype.ngOnInit || null,
|
||||
doCheck: type.prototype.ngDoCheck || null,
|
||||
afterContentInit: type.prototype.ngAfterContentInit || null,
|
||||
afterContentChecked: type.prototype.ngAfterContentChecked || null,
|
||||
afterViewInit: type.prototype.ngAfterViewInit || null,
|
||||
afterViewChecked: type.prototype.ngAfterViewChecked || null,
|
||||
onDestroy: type.prototype.ngOnDestroy || null
|
||||
},
|
||||
feature = componentDefinition.features;
|
||||
feature && feature.forEach(function(fn) { return fn(def); });
|
||||
return def;
|
||||
}({
|
||||
type: HelloWorld,
|
||||
tag: 'hello-world',
|
||||
factory: function() { return new HelloWorld(); },
|
||||
template: function(ctx, cm) {
|
||||
cm && function(index, value) {
|
||||
createLNode(0, 3, null);
|
||||
isParent = !1;
|
||||
}();
|
||||
!function(index, value) {
|
||||
var existingNode = data[0];
|
||||
if (existingNode.native)
|
||||
value !== NO_CHANGE &&
|
||||
(renderer.setValue ?
|
||||
renderer.setValue(existingNode.native, stringify$1(value)) :
|
||||
existingNode.native.textContent = stringify$1(value));
|
||||
else {
|
||||
existingNode.native = renderer.createText ?
|
||||
renderer.createText(stringify$1(value)) :
|
||||
renderer.createTextNode(stringify$1(value));
|
||||
!function(node, currentView) {
|
||||
var parent = node.parent;
|
||||
if (canInsertNativeNode(parent, currentView)) {
|
||||
var nativeSibling = function(node, stopNode) {
|
||||
for (var currentNode = node; currentNode && null !== currentNode;) {
|
||||
var pNextOrParent = currentNode.pNextOrParent;
|
||||
if (pNextOrParent) {
|
||||
for (var pNextOrParentType = 3 & pNextOrParent.flags;
|
||||
1 !== pNextOrParentType;) {
|
||||
if (nativeNode = findFirstRNode(pNextOrParent)) return nativeNode;
|
||||
pNextOrParent = pNextOrParent.pNextOrParent;
|
||||
}
|
||||
currentNode = pNextOrParent;
|
||||
} else {
|
||||
for (var currentSibling = currentNode.next; currentSibling;) {
|
||||
var nativeNode;
|
||||
if (nativeNode = findFirstRNode(currentSibling)) return nativeNode;
|
||||
currentSibling = currentSibling.next;
|
||||
}
|
||||
var parentNode = currentNode.parent;
|
||||
currentNode = null;
|
||||
if (parentNode) {
|
||||
var parentType = 3 & parentNode.flags;
|
||||
0 !== parentType && 2 !== parentType || (currentNode = parentNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}(node), renderer = currentView.renderer;
|
||||
renderer.listen ?
|
||||
renderer.insertBefore(parent.native, node.native, nativeSibling) :
|
||||
parent.native.insertBefore(node.native, nativeSibling, !1);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
/**
|
||||
* @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
|
||||
*/ (existingNode, currentView);
|
||||
}
|
||||
}(0, function(prefix, value, suffix) {
|
||||
return function(value) {
|
||||
if (creationMode) {
|
||||
!function() {
|
||||
null == currentView.bindingStartIndex &&
|
||||
(bindingIndex = currentView.bindingStartIndex = data.length);
|
||||
}();
|
||||
return data[bindingIndex++] = value;
|
||||
}
|
||||
var changed = value !== NO_CHANGE && function(a, b) {
|
||||
return !(a != a && value != value) && a !== value;
|
||||
}(data[bindingIndex]);
|
||||
changed && (data[bindingIndex] = value);
|
||||
bindingIndex++;
|
||||
return changed ? value : NO_CHANGE;
|
||||
}(value) === NO_CHANGE ?
|
||||
NO_CHANGE :
|
||||
'Hello ' + stringify$1(value) + '!';
|
||||
}(0, ctx.name));
|
||||
}
|
||||
});
|
||||
return HelloWorld;
|
||||
}());
|
||||
}();
|
|
@ -0,0 +1,28 @@
|
|||
[ "EMPTY$1",
|
||||
"NO_CHANGE",
|
||||
"Symbol$1",
|
||||
"__global$1",
|
||||
"__self$1",
|
||||
"__window$1",
|
||||
"_renderCompCount",
|
||||
"_root",
|
||||
"createLNode",
|
||||
"createLView",
|
||||
"domRendererFactory3",
|
||||
"enterView",
|
||||
"invertObject",
|
||||
"leaveView",
|
||||
"locateHostElement",
|
||||
"noop$2",
|
||||
"refreshDynamicChildren",
|
||||
"renderComponentOrTemplate",
|
||||
"renderEmbeddedTemplate",
|
||||
"stringify$1",
|
||||
"canInsertNativeNode",
|
||||
"createTView",
|
||||
"executeHooks",
|
||||
"findFirstRNode",
|
||||
"getDirectiveInstance",
|
||||
"getNextLNodeWithProjection",
|
||||
"getNextOrParentSiblingNode"
|
||||
]
|
|
@ -0,0 +1,9 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
(function() { var Class = function() {}, fn = function() {}; })();
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
{
|
||||
"name": "Class"
|
||||
},
|
||||
{
|
||||
"name": "fn"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
!function() {
|
||||
'use strict';
|
||||
// tslint:disable-next-line:no-console
|
||||
console.log('Hello, Alice in Wonderland');
|
||||
var A = function() {
|
||||
function A() {}
|
||||
return A.prototype.a = function() { return document.a; }, A;
|
||||
}(), B = function() {
|
||||
function B() {}
|
||||
return B.prototype.b = function() { return window.b; }, B;
|
||||
}();
|
||||
var ignore_no_initializer;
|
||||
// tslint:disable-next-line:no-console
|
||||
console.error(new A().a(), new B().b());
|
||||
}();
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
{
|
||||
"name": "A"
|
||||
},
|
||||
{
|
||||
"name": "B"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
!function() {
|
||||
'use strict';
|
||||
var constant = 1, method = function() {}, clazz = class {};
|
||||
}();
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
"clazz",
|
||||
"constant",
|
||||
"method"
|
||||
]
|
Loading…
Reference in New Issue