refactor(view_compiler): codegen DI and Queries
BREAKING CHANGE: - Renderer: * renderComponent method is removed form `Renderer`, only present on `RootRenderer` * Renderer.setDebugInfo is removed. Renderer.createElement / createText / createTemplateAnchor now take the DebugInfo directly. - Query semantics: * Queries don't work with dynamically loaded components. * e.g. for router-outlet: loaded components can't be queries via @ViewQuery, but router-outlet emits an event `activate` now that emits the activated component - Exception classes and the context inside changed (renamed fields) - DebugElement.attributes is an Object and not a Map in JS any more - ChangeDetectorGenConfig was renamed into CompilerConfig - AppViewManager.createEmbeddedViewInContainer / AppViewManager.createHostViewInContainer are removed, use the methods in ViewContainerRef instead - Change detection order changed: * 1. dirty check component inputs * 2. dirty check content children * 3. update render nodes Closes #6301 Closes #6567
This commit is contained in:
@ -17,7 +17,8 @@ class CheckImports implements DiffingBroccoliPlugin {
|
||||
"angular2/src/facade": ["rxjs"],
|
||||
"angular2/src/common": ["angular2/core", "angular2/src/facade"],
|
||||
"angular2/src/http": ["angular2/core", "angular2/src/facade", "rxjs"],
|
||||
"angular2/src/upgrade": ["angular2/core", "angular2/src/facade", "angular2/platform/browser"]
|
||||
"angular2/src/upgrade":
|
||||
["angular2/core", "angular2/src/facade", "angular2/platform/browser", "angular2/compiler"]
|
||||
//"angular2/src/render": [
|
||||
// "angular2/animate",
|
||||
// "angular2/core",
|
||||
|
81
tools/broccoli/broccoli-generate-for-test.ts
Normal file
81
tools/broccoli/broccoli-generate-for-test.ts
Normal file
@ -0,0 +1,81 @@
|
||||
import fs = require('fs');
|
||||
import fse = require('fs-extra');
|
||||
import path = require('path');
|
||||
import childProcess = require('child_process');
|
||||
var glob = require('glob');
|
||||
|
||||
import {wrapDiffingPlugin, DiffingBroccoliPlugin, DiffResult} from './diffing-broccoli-plugin';
|
||||
|
||||
/**
|
||||
* Intercepts each changed file and replaces its contents with
|
||||
* the output of the generator.
|
||||
*/
|
||||
class GeneratorForTest implements DiffingBroccoliPlugin {
|
||||
private seenFiles: {[key: string]: boolean} = {};
|
||||
|
||||
constructor(private inputPath, private outputPath, private options) {}
|
||||
|
||||
rebuild(treeDiff: DiffResult) {
|
||||
var matchedFiles = [];
|
||||
this.options.files.forEach(
|
||||
(file) => { matchedFiles = matchedFiles.concat(glob.sync(file, {cwd: this.inputPath})); });
|
||||
return Promise.all(matchedFiles.map((matchedFile) => {
|
||||
var inputFilePath = path.join(this.inputPath, matchedFile);
|
||||
var outputFilePath = path.join(this.outputPath, matchedFile);
|
||||
|
||||
var outputDirPath = path.dirname(outputFilePath);
|
||||
if (!fs.existsSync(outputDirPath)) {
|
||||
fse.mkdirpSync(outputDirPath);
|
||||
}
|
||||
return this.invokeGenerator(matchedFile, inputFilePath, outputFilePath)
|
||||
}))
|
||||
.then(() => {
|
||||
var result = new DiffResult();
|
||||
matchedFiles.forEach((file) => {
|
||||
if (!this.seenFiles[file]) {
|
||||
result.addedPaths.push(file);
|
||||
this.seenFiles[file] = true;
|
||||
} else {
|
||||
result.changedPaths.push(file);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
private invokeGenerator(file: string, inputFilePath: string,
|
||||
outputFilePath: string): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
var args;
|
||||
var vmPath;
|
||||
var env;
|
||||
if (this.options.dartPath) {
|
||||
vmPath = this.options.dartPath;
|
||||
args = [`--package-root=${this.inputPath}`, '--checked', inputFilePath, file];
|
||||
env = {};
|
||||
} else {
|
||||
vmPath = process.execPath;
|
||||
var script = `require('reflect-metadata');require('${inputFilePath}').main(['${file}']);`;
|
||||
args = ['-e', script];
|
||||
env = {'NODE_PATH': this.inputPath};
|
||||
}
|
||||
|
||||
var stdoutStream = fs.createWriteStream(outputFilePath);
|
||||
var proc = childProcess.spawn(
|
||||
vmPath, args,
|
||||
{stdio: ['ignore', 'pipe', 'inherit'], env: Object['assign']({}, process.env, env)});
|
||||
proc.on('error', function(code) {
|
||||
console.error(code);
|
||||
reject(new Error('Failed while generating code. Please run manually: ' + vmPath + ' ' +
|
||||
args.join(' ')));
|
||||
});
|
||||
proc.on('close', function() {
|
||||
stdoutStream.close();
|
||||
resolve();
|
||||
});
|
||||
proc.stdout.pipe(stdoutStream);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default wrapDiffingPlugin(GeneratorForTest);
|
@ -12,6 +12,7 @@ import ts2dart from '../broccoli-ts2dart';
|
||||
import dartfmt from '../broccoli-dartfmt';
|
||||
import replace from '../broccoli-replace';
|
||||
import {AngularBuilderOptions} from '../angular_builder';
|
||||
import generateForTest from '../broccoli-generate-for-test';
|
||||
|
||||
var global_excludes = [
|
||||
'angular2/examples/**/ts/**/*',
|
||||
@ -61,17 +62,26 @@ function stripModulePrefix(relativePath: string): string {
|
||||
return relativePath.replace(/^modules\//, '');
|
||||
}
|
||||
|
||||
function getSourceTree() {
|
||||
function getSourceTree(options: AngularBuilderOptions) {
|
||||
var tsInputTree = modulesFunnel(['**/*.js', '**/*.ts', '**/*.dart'], ['angular1_router/**/*']);
|
||||
var transpiled = ts2dart(tsInputTree, {
|
||||
generateLibraryName: true,
|
||||
generateSourceMap: false,
|
||||
translateBuiltins: true,
|
||||
});
|
||||
|
||||
// Native sources, dart only examples, etc.
|
||||
var dartSrcs = modulesFunnel(
|
||||
['**/*.dart', '**/*.ng_meta.json', '**/*.aliases.json', '**/css/**', '**/*.css']);
|
||||
return mergeTrees([transpiled, dartSrcs]);
|
||||
|
||||
var compiledTree = mergeTrees([transpiled, dartSrcs]);
|
||||
|
||||
// Generate test files
|
||||
let generatedDartTestFiles = generateForTest(
|
||||
mergeTrees([compiledTree, new Funnel('packages', {include: ['path/**', 'stack_trace/**']})]),
|
||||
{files: ['*/test/**/*_codegen_typed.dart'], dartPath: options.dartSDK.VM});
|
||||
|
||||
return mergeTrees([compiledTree, generatedDartTestFiles], {overwrite: true});
|
||||
}
|
||||
|
||||
function fixDartFolderLayout(sourceTree) {
|
||||
@ -169,7 +179,7 @@ function getDocsTree() {
|
||||
}
|
||||
|
||||
module.exports = function makeDartTree(options: AngularBuilderOptions) {
|
||||
var dartSources = dartfmt(getSourceTree(), {dartSDK: options.dartSDK, logs: options.logs});
|
||||
var dartSources = dartfmt(getSourceTree(options), {dartSDK: options.dartSDK, logs: options.logs});
|
||||
var sourceTree = mergeTrees([dartSources, getHtmlSourcesTree(), getExamplesJsonTree()]);
|
||||
sourceTree = fixDartFolderLayout(sourceTree);
|
||||
|
||||
|
@ -8,6 +8,7 @@ import mergeTrees from '../broccoli-merge-trees';
|
||||
var path = require('path');
|
||||
import renderLodashTemplate from '../broccoli-lodash';
|
||||
import replace from '../broccoli-replace';
|
||||
import generateForTest from '../broccoli-generate-for-test';
|
||||
var stew = require('broccoli-stew');
|
||||
var writeFile = require('broccoli-file-creator');
|
||||
|
||||
@ -120,16 +121,41 @@ module.exports = function makeNodeTree(projects, destinationPath) {
|
||||
|
||||
let compiledTree = mergeTrees([compiledSrcTree, compiledTestTree]);
|
||||
|
||||
// Generate test files
|
||||
let generatedJsTestFiles =
|
||||
generateForTest(compiledTree, {files: ['*/test/**/*_codegen_untyped.js']});
|
||||
let generatedTsTestFiles = stew.rename(
|
||||
generateForTest(compiledTree, {files: ['*/test/**/*_codegen_typed.js']}), /.js$/, '.ts');
|
||||
|
||||
// Compile generated test files against the src @internal .d.ts and the test files
|
||||
compiledTree = mergeTrees(
|
||||
[
|
||||
compiledTree,
|
||||
generatedJsTestFiles,
|
||||
compileTree(
|
||||
new Funnel(
|
||||
mergeTrees([
|
||||
packageTypings,
|
||||
new Funnel('modules',
|
||||
{include: ['angular2/manual_typings/**', 'angular2/typings/**']}),
|
||||
generatedTsTestFiles,
|
||||
srcPrivateDeclarations,
|
||||
compiledTestTree
|
||||
]),
|
||||
{include: ['angular2/**', 'rxjs/**', 'zone.js/**']}),
|
||||
false, [])
|
||||
],
|
||||
{overwrite: true});
|
||||
|
||||
// Down-level .d.ts files to be TS 1.8 compatible
|
||||
// TODO(alexeagle): this can be removed once we drop support for using Angular 2 with TS 1.8
|
||||
compiledTree = replace(compiledTree, {
|
||||
files: ['**/*.d.ts'],
|
||||
patterns: [
|
||||
{match: /^(\s*(static\s+)?)readonly\s+/mg, replacement: "$1"},
|
||||
{match: /^(\s*(static\s+|private\s+)*)readonly\s+/mg, replacement: "$1"},
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
// Now we add the LICENSE file into all the folders that will become npm packages
|
||||
outputPackages.forEach(function(destDir) {
|
||||
var license = new Funnel('.', {files: ['LICENSE'], destDir: destDir});
|
||||
|
Reference in New Issue
Block a user