feat(ivy): @NgModule -> ngInjectorDef compilation (#22458)

This adds compilation of @NgModule providers and imports into
ngInjectorDef statements in generated code. All @NgModule annotations
will be compiled and the @NgModule decorators removed from the
resultant js output.

All @Injectables will also be compiled in Ivy mode, and the decorator
removed.

PR Close #22458
This commit is contained in:
Alex Rickabaugh
2018-02-16 08:45:21 -08:00
committed by Miško Hevery
parent 688096b7a3
commit 6ef9f2278f
48 changed files with 2044 additions and 206 deletions

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {CompileDirectiveMetadata, CompileDirectiveSummary, CompileIdentifierMetadata, CompileInjectableMetadata, CompileNgModuleMetadata, CompileNgModuleSummary, CompilePipeMetadata, CompilePipeSummary, CompileProviderMetadata, CompileStylesheetMetadata, CompileSummaryKind, CompileTypeMetadata, CompileTypeSummary, componentFactoryName, flatten, identifierName, templateSourceUrl, tokenReference} from '../compile_metadata';
import {CompileDirectiveMetadata, CompileDirectiveSummary, CompileIdentifierMetadata, CompileInjectableMetadata, CompileNgModuleMetadata, CompileNgModuleSummary, CompilePipeMetadata, CompilePipeSummary, CompileProviderMetadata, CompileShallowModuleMetadata, CompileStylesheetMetadata, CompileSummaryKind, CompileTypeMetadata, CompileTypeSummary, componentFactoryName, flatten, identifierName, templateSourceUrl, tokenReference} from '../compile_metadata';
import {CompilerConfig} from '../config';
import {ConstantPool} from '../constant_pool';
import {ViewEncapsulation} from '../core';
@ -20,6 +20,7 @@ import {NgModuleCompiler} from '../ng_module_compiler';
import {OutputEmitter} from '../output/abstract_emitter';
import * as o from '../output/output_ast';
import {ParseError} from '../parse_util';
import {compileNgModule as compileIvyModule} from '../render3/r3_module_compiler';
import {compilePipe as compileIvyPipe} from '../render3/r3_pipe_compiler';
import {OutputMode} from '../render3/r3_types';
import {compileComponent as compileIvyComponent, compileDirective as compileIvyDirective} from '../render3/r3_view_compiler';
@ -57,7 +58,7 @@ export class AotCompiler {
constructor(
private _config: CompilerConfig, private _options: AotCompilerOptions,
private _host: AotCompilerHost, private _reflector: StaticReflector,
private _host: AotCompilerHost, readonly reflector: StaticReflector,
private _metadataResolver: CompileMetadataResolver, private _templateParser: TemplateParser,
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
private _typeCheckCompiler: TypeCheckCompiler, private _ngModuleCompiler: NgModuleCompiler,
@ -283,7 +284,7 @@ export class AotCompiler {
private _externalIdentifierReferences(references: o.ExternalReference[]): StaticSymbol[] {
const result: StaticSymbol[] = [];
for (let reference of references) {
const token = createTokenForExternalReference(this._reflector, reference);
const token = createTokenForExternalReference(this.reflector, reference);
if (token.identifier) {
result.push(token.identifier.reference);
}
@ -332,28 +333,49 @@ export class AotCompiler {
return messageBundle;
}
emitAllPartialModules({ngModuleByPipeOrDirective, files}: NgAnalyzedModules): PartialModule[] {
// Using reduce like this is a select many pattern (where map is a select pattern)
return files.reduce<PartialModule[]>((r, file) => {
r.push(...this._emitPartialModule(
file.fileName, ngModuleByPipeOrDirective, file.directives, file.pipes, file.ngModules,
file.injectables));
return r;
}, []);
emitAllPartialModules(
{ngModuleByPipeOrDirective, files}: NgAnalyzedModules,
r3Files: NgAnalyzedFileWithInjectables[]): PartialModule[] {
const contextMap = new Map<string, OutputContext>();
const getContext = (fileName: string): OutputContext => {
if (!contextMap.has(fileName)) {
contextMap.set(fileName, this._createOutputContext(fileName));
}
return contextMap.get(fileName) !;
};
files.forEach(
file => this._compilePartialModule(
file.fileName, ngModuleByPipeOrDirective, file.directives, file.pipes, file.ngModules,
file.injectables, getContext(file.fileName)));
r3Files.forEach(
file => this._compileShallowModules(
file.fileName, file.shallowModules, getContext(file.fileName)));
return Array.from(contextMap.values())
.map(context => ({
fileName: context.genFilePath,
statements: [...context.constantPool.statements, ...context.statements],
}));
}
private _emitPartialModule(
private _compileShallowModules(
fileName: string, shallowModules: CompileShallowModuleMetadata[],
context: OutputContext): void {
shallowModules.forEach(module => compileIvyModule(context, module, this._injectableCompiler));
}
private _compilePartialModule(
fileName: string, ngModuleByPipeOrDirective: Map<StaticSymbol, CompileNgModuleMetadata>,
directives: StaticSymbol[], pipes: StaticSymbol[], ngModules: CompileNgModuleMetadata[],
injectables: CompileInjectableMetadata[]): PartialModule[] {
injectables: CompileInjectableMetadata[], context: OutputContext): void {
const classes: o.ClassStmt[] = [];
const errors: ParseError[] = [];
const context = this._createOutputContext(fileName);
const hostBindingParser = new BindingParser(
this._templateParser.expressionParser, DEFAULT_INTERPOLATION_CONFIG, null !, [], errors);
// Process all components and directives
directives.forEach(directiveType => {
const directiveMetadata = this._metadataResolver.getDirectiveMetadata(directiveType);
@ -366,28 +388,22 @@ export class AotCompiler {
const {template: parsedTemplate, pipes: parsedPipes} =
this._parseTemplate(directiveMetadata, module, module.transitiveModule.directives);
compileIvyComponent(
context, directiveMetadata, parsedPipes, parsedTemplate, this._reflector,
context, directiveMetadata, parsedPipes, parsedTemplate, this.reflector,
hostBindingParser, OutputMode.PartialClass);
} else {
compileIvyDirective(
context, directiveMetadata, this._reflector, hostBindingParser,
OutputMode.PartialClass);
context, directiveMetadata, this.reflector, hostBindingParser, OutputMode.PartialClass);
}
});
pipes.forEach(pipeType => {
const pipeMetadata = this._metadataResolver.getPipeMetadata(pipeType);
if (pipeMetadata) {
compileIvyPipe(context, pipeMetadata, this._reflector, OutputMode.PartialClass);
compileIvyPipe(context, pipeMetadata, this.reflector, OutputMode.PartialClass);
}
});
injectables.forEach(injectable => this._injectableCompiler.compile(injectable, context));
if (context.statements && context.statements.length > 0) {
return [{fileName, statements: [...context.constantPool.statements, ...context.statements]}];
}
return [];
}
emitAllPartialModules2(files: NgAnalyzedFileWithInjectables[]): PartialModule[] {
@ -531,14 +547,14 @@ export class AotCompiler {
if (this._options.locale) {
const normalizedLocale = this._options.locale.replace(/_/g, '-');
providers.push({
token: createTokenForExternalReference(this._reflector, Identifiers.LOCALE_ID),
token: createTokenForExternalReference(this.reflector, Identifiers.LOCALE_ID),
useValue: normalizedLocale,
});
}
if (this._options.i18nFormat) {
providers.push({
token: createTokenForExternalReference(this._reflector, Identifiers.TRANSLATIONS_FORMAT),
token: createTokenForExternalReference(this.reflector, Identifiers.TRANSLATIONS_FORMAT),
useValue: this._options.i18nFormat
});
}
@ -682,12 +698,12 @@ export class AotCompiler {
listLazyRoutes(entryRoute?: string, analyzedModules?: NgAnalyzedModules): LazyRoute[] {
const self = this;
if (entryRoute) {
const symbol = parseLazyRoute(entryRoute, this._reflector).referencedModule;
const symbol = parseLazyRoute(entryRoute, this.reflector).referencedModule;
return visitLazyRoute(symbol);
} else if (analyzedModules) {
const allLazyRoutes: LazyRoute[] = [];
for (const ngModule of analyzedModules.ngModules) {
const lazyRoutes = listLazyRoutes(ngModule, this._reflector);
const lazyRoutes = listLazyRoutes(ngModule, this.reflector);
for (const lazyRoute of lazyRoutes) {
allLazyRoutes.push(lazyRoute);
}
@ -707,7 +723,7 @@ export class AotCompiler {
}
seenRoutes.add(symbol);
const lazyRoutes = listLazyRoutes(
self._metadataResolver.getNgModuleMetadata(symbol, true) !, self._reflector);
self._metadataResolver.getNgModuleMetadata(symbol, true) !, self.reflector);
for (const lazyRoute of lazyRoutes) {
allLazyRoutes.push(lazyRoute);
visitLazyRoute(lazyRoute.referencedModule, seenRoutes, allLazyRoutes);
@ -748,6 +764,7 @@ export interface NgAnalyzedModules {
export interface NgAnalyzedFileWithInjectables {
fileName: string;
injectables: CompileInjectableMetadata[];
shallowModules: CompileShallowModuleMetadata[];
}
export interface NgAnalyzedFile {
@ -868,6 +885,7 @@ export function analyzeFileForInjectables(
host: NgAnalyzeModulesHost, staticSymbolResolver: StaticSymbolResolver,
metadataResolver: CompileMetadataResolver, fileName: string): NgAnalyzedFileWithInjectables {
const injectables: CompileInjectableMetadata[] = [];
const shallowModules: CompileShallowModuleMetadata[] = [];
if (staticSymbolResolver.hasDecorators(fileName)) {
staticSymbolResolver.getSymbolsOf(fileName).forEach((symbol) => {
const resolvedSymbol = staticSymbolResolver.resolveSymbol(symbol);
@ -883,11 +901,17 @@ export function analyzeFileForInjectables(
if (injectable) {
injectables.push(injectable);
}
} else if (metadataResolver.isNgModule(symbol)) {
isNgSymbol = true;
const module = metadataResolver.getShallowModuleMetadata(symbol);
if (module) {
shallowModules.push(module);
}
}
}
});
}
return {fileName, injectables};
return {fileName, injectables, shallowModules};
}
function isValueExportingNonSourceFile(host: NgAnalyzeModulesHost, metadata: any): boolean {

View File

@ -90,7 +90,8 @@ export function createAotCompiler(
const compiler = new AotCompiler(
config, options, compilerHost, staticReflector, resolver, tmplParser,
new StyleCompiler(urlResolver), viewCompiler, typeCheckCompiler,
new NgModuleCompiler(staticReflector), new InjectableCompiler(staticReflector),
new TypeScriptEmitter(), summaryResolver, symbolResolver);
new NgModuleCompiler(staticReflector),
new InjectableCompiler(staticReflector, !!options.enableIvy), new TypeScriptEmitter(),
summaryResolver, symbolResolver);
return {compiler, reflector: staticReflector};
}

View File

@ -18,4 +18,5 @@ export interface AotCompilerOptions {
fullTemplateTypeCheck?: boolean;
allowEmptyCodegenFiles?: boolean;
strictInjectionParameters?: boolean;
enableIvy?: boolean;
}

View File

@ -42,6 +42,7 @@ function shouldIgnore(value: any): boolean {
*/
export class StaticReflector implements CompileReflector {
private annotationCache = new Map<StaticSymbol, any[]>();
private shallowAnnotationCache = new Map<StaticSymbol, any[]>();
private propertyCache = new Map<StaticSymbol, {[key: string]: any[]}>();
private parameterCache = new Map<StaticSymbol, any[]>();
private methodCache = new Map<StaticSymbol, {[key: string]: boolean}>();
@ -106,8 +107,9 @@ export class StaticReflector implements CompileReflector {
this.symbolResolver.getSymbolByModule(moduleUrl, name, containingFile));
}
tryFindDeclaration(moduleUrl: string, name: string): StaticSymbol {
return this.symbolResolver.ignoreErrorsFor(() => this.findDeclaration(moduleUrl, name));
tryFindDeclaration(moduleUrl: string, name: string, containingFile?: string): StaticSymbol {
return this.symbolResolver.ignoreErrorsFor(
() => this.findDeclaration(moduleUrl, name, containingFile));
}
findSymbolDeclaration(symbol: StaticSymbol): StaticSymbol {
@ -135,7 +137,21 @@ export class StaticReflector implements CompileReflector {
}
public annotations(type: StaticSymbol): any[] {
let annotations = this.annotationCache.get(type);
return this._annotations(
type, (type: StaticSymbol, decorators: any) => this.simplify(type, decorators),
this.annotationCache);
}
public shallowAnnotations(type: StaticSymbol): any[] {
return this._annotations(
type, (type: StaticSymbol, decorators: any) => this.simplify(type, decorators, true),
this.shallowAnnotationCache);
}
private _annotations(
type: StaticSymbol, simplify: (type: StaticSymbol, decorators: any) => any,
annotationCache: Map<StaticSymbol, any[]>): any[] {
let annotations = annotationCache.get(type);
if (!annotations) {
annotations = [];
const classMetadata = this.getTypeMetadata(type);
@ -146,7 +162,7 @@ export class StaticReflector implements CompileReflector {
}
let ownAnnotations: any[] = [];
if (classMetadata['decorators']) {
ownAnnotations = this.simplify(type, classMetadata['decorators']);
ownAnnotations = simplify(type, classMetadata['decorators']);
annotations.push(...ownAnnotations);
}
if (parentType && !this.summaryResolver.isLibraryFile(type.filePath) &&
@ -169,7 +185,7 @@ export class StaticReflector implements CompileReflector {
}
}
}
this.annotationCache.set(type, annotations.filter(ann => !!ann));
annotationCache.set(type, annotations.filter(ann => !!ann));
}
return annotations;
}
@ -414,7 +430,7 @@ export class StaticReflector implements CompileReflector {
}
/** @internal */
public simplify(context: StaticSymbol, value: any): any {
public simplify(context: StaticSymbol, value: any, lazy: boolean = false): any {
const self = this;
let scope = BindingScope.empty;
const calling = new Map<StaticSymbol, boolean>();
@ -775,7 +791,7 @@ export class StaticReflector implements CompileReflector {
let result: any;
try {
result = simplifyInContext(context, value, 0, 0);
result = simplifyInContext(context, value, 0, lazy ? 1 : 0);
} catch (e) {
if (this.errorRecorder) {
this.reportError(e, context);

View File

@ -527,6 +527,14 @@ export interface CompileNgModuleSummary extends CompileTypeSummary {
modules: CompileTypeMetadata[];
}
export class CompileShallowModuleMetadata {
type: CompileTypeMetadata;
rawExports: any;
rawImports: any;
rawProviders: any;
}
/**
* Metadata regarding compilation of a module.
*/

View File

@ -15,6 +15,7 @@ import * as o from './output/output_ast';
export abstract class CompileReflector {
abstract parameters(typeOrFunc: /*Type*/ any): any[][];
abstract annotations(typeOrFunc: /*Type*/ any): any[];
abstract shallowAnnotations(typeOrFunc: /*Type*/ any): any[];
abstract tryAnnotations(typeOrFunc: /*Type*/ any): any[];
abstract propMetadata(typeOrFunc: /*Type*/ any): {[key: string]: any[]};
abstract hasLifecycleHook(type: any, lcProperty: string): boolean;

View File

@ -62,6 +62,7 @@ export class Identifiers {
};
static inject: o.ExternalReference = {name: 'inject', moduleName: CORE};
static INJECTOR: o.ExternalReference = {name: 'INJECTOR', moduleName: CORE};
static Injector: o.ExternalReference = {name: 'Injector', moduleName: CORE};
static defineInjectable: o.ExternalReference = {name: 'defineInjectable', moduleName: CORE};
static ViewEncapsulation: o.ExternalReference = {
@ -88,7 +89,6 @@ export class Identifiers {
static inlineInterpolate: o.ExternalReference = {
name: 'ɵinlineInterpolate',
moduleName: CORE,
};
static interpolate: o.ExternalReference = {name: 'ɵinterpolate', moduleName: CORE};
static EMPTY_ARRAY: o.ExternalReference = {name: 'ɵEMPTY_ARRAY', moduleName: CORE};

View File

@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {StaticSymbol} from './aot/static_symbol';
import {CompileInjectableMetadata, CompileNgModuleMetadata, CompileProviderMetadata, identifierName} from './compile_metadata';
import {CompileReflector} from './compile_reflector';
import {InjectFlags, NodeFlags} from './core';
@ -29,7 +30,10 @@ function mapEntry(key: string, value: o.Expression): MapEntry {
}
export class InjectableCompiler {
constructor(private reflector: CompileReflector) {}
private tokenInjector: StaticSymbol;
constructor(private reflector: CompileReflector, private alwaysGenerateDef: boolean) {
this.tokenInjector = reflector.resolveExternalReference(Identifiers.Injector);
}
private depsArray(deps: any[], ctx: OutputContext): o.Expression[] {
return deps.map(dep => {
@ -55,7 +59,16 @@ export class InjectableCompiler {
}
}
}
const tokenExpr = typeof token === 'string' ? o.literal(token) : ctx.importExpr(token);
let tokenExpr: o.Expression;
if (typeof token === 'string') {
tokenExpr = o.literal(token);
} else if (token === this.tokenInjector && this.alwaysGenerateDef) {
tokenExpr = o.importExpr(Identifiers.INJECTOR);
} else {
tokenExpr = ctx.importExpr(token);
}
if (flags !== InjectFlags.Default || defaultValue !== undefined) {
args = [tokenExpr, o.literal(defaultValue), o.literal(flags)];
} else {
@ -65,7 +78,7 @@ export class InjectableCompiler {
});
}
private factoryFor(injectable: CompileInjectableMetadata, ctx: OutputContext): o.Expression {
factoryFor(injectable: CompileInjectableMetadata, ctx: OutputContext): o.Expression {
let retValue: o.Expression;
if (injectable.useExisting) {
retValue = o.importExpr(Identifiers.inject).callFn([ctx.importExpr(injectable.useExisting)]);
@ -90,8 +103,10 @@ export class InjectableCompiler {
injectableDef(injectable: CompileInjectableMetadata, ctx: OutputContext): o.Expression {
let providedIn: o.Expression = o.NULL_EXPR;
if (injectable.providedIn) {
if (typeof injectable.providedIn === 'string') {
if (injectable.providedIn !== undefined) {
if (injectable.providedIn === null) {
providedIn = o.NULL_EXPR;
} else if (typeof injectable.providedIn === 'string') {
providedIn = o.literal(injectable.providedIn);
} else {
providedIn = ctx.importExpr(injectable.providedIn);
@ -106,7 +121,7 @@ export class InjectableCompiler {
}
compile(injectable: CompileInjectableMetadata, ctx: OutputContext): void {
if (injectable.providedIn) {
if (this.alwaysGenerateDef || injectable.providedIn !== undefined) {
const className = identifierName(injectable.type) !;
const clazz = new o.ClassStmt(
className, null,

View File

@ -12,9 +12,9 @@ import {assertArrayOfStrings, assertInterpolationSymbols} from './assertions';
import * as cpl from './compile_metadata';
import {CompileReflector} from './compile_reflector';
import {CompilerConfig} from './config';
import {ChangeDetectionStrategy, Component, Directive, Injectable, ModuleWithProviders, Provider, Query, SchemaMetadata, Type, ViewEncapsulation, createAttribute, createComponent, createHost, createInject, createInjectable, createInjectionToken, createOptional, createSelf, createSkipSelf} from './core';
import {ChangeDetectionStrategy, Component, Directive, Injectable, ModuleWithProviders, Provider, Query, SchemaMetadata, Type, ViewEncapsulation, createAttribute, createComponent, createHost, createInject, createInjectable, createInjectionToken, createNgModule, createOptional, createSelf, createSkipSelf} from './core';
import {DirectiveNormalizer} from './directive_normalizer';
import {DirectiveResolver} from './directive_resolver';
import {DirectiveResolver, findLast} from './directive_resolver';
import {Identifiers} from './identifiers';
import {getAllLifecycleHooks} from './lifecycle_reflector';
import {HtmlParser} from './ml_parser/html_parser';
@ -44,6 +44,7 @@ export class CompileMetadataResolver {
private _pipeCache = new Map<Type, cpl.CompilePipeMetadata>();
private _ngModuleCache = new Map<Type, cpl.CompileNgModuleMetadata>();
private _ngModuleOfTypes = new Map<Type, Type>();
private _shallowModuleCache = new Map<Type, cpl.CompileShallowModuleMetadata>();
constructor(
private _config: CompilerConfig, private _htmlParser: HtmlParser,
@ -477,6 +478,26 @@ export class CompileMetadataResolver {
return Promise.all(loading);
}
getShallowModuleMetadata(moduleType: any): cpl.CompileShallowModuleMetadata|null {
let compileMeta = this._shallowModuleCache.get(moduleType);
if (compileMeta) {
return compileMeta;
}
const ngModuleMeta =
findLast(this._reflector.shallowAnnotations(moduleType), createNgModule.isTypeOf);
compileMeta = {
type: this._getTypeMetadata(moduleType),
rawExports: ngModuleMeta.exports,
rawImports: ngModuleMeta.imports,
rawProviders: ngModuleMeta.providers,
};
this._shallowModuleCache.set(moduleType, compileMeta);
return compileMeta;
}
getNgModuleMetadata(
moduleType: any, throwIfNotFound = true,
alreadyCollecting: Set<any>|null = null): cpl.CompileNgModuleMetadata|null {

View File

@ -0,0 +1,29 @@
/**
* @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 o from './output_ast';
export type MapEntry = {
key: string,
quoted: boolean,
value: o.Expression
};
export type MapLiteral = MapEntry[];
export function mapEntry(key: string, value: o.Expression): MapEntry {
return {key, value, quoted: false};
}
export function mapLiteral(obj: {[key: string]: o.Expression}): o.Expression {
return o.literalMap(Object.keys(obj).map(key => ({
key,
quoted: false,
value: obj[key],
})));
}

View File

@ -102,6 +102,11 @@ export class Identifiers {
moduleName: CORE,
};
static defineInjector: o.ExternalReference = {
name: 'defineInjector',
moduleName: CORE,
};
static definePipe: o.ExternalReference = {name: 'ɵdefinePipe', moduleName: CORE};
static query: o.ExternalReference = {name: 'ɵQ', moduleName: CORE};

View File

@ -0,0 +1,60 @@
/**
* @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 {StaticSymbol} from '../aot/static_symbol';
import {CompileShallowModuleMetadata, identifierName} from '../compile_metadata';
import {InjectableCompiler} from '../injectable_compiler';
import {mapLiteral} from '../output/map_util';
import * as o from '../output/output_ast';
import {OutputContext} from '../util';
import {Identifiers as R3} from './r3_identifiers';
const EMPTY_ARRAY = o.literalArr([]);
function convertMetaToOutput(meta: any, ctx: OutputContext): o.Expression {
if (Array.isArray(meta)) {
return o.literalArr(meta.map(entry => convertMetaToOutput(entry, ctx)));
} else if (meta instanceof StaticSymbol) {
return ctx.importExpr(meta);
} else if (meta == null) {
return o.literal(meta);
} else {
throw new Error(`Internal error: Unsupported or unknown metadata: ${meta}`);
}
}
export function compileNgModule(
ctx: OutputContext, ngModule: CompileShallowModuleMetadata,
injectableCompiler: InjectableCompiler): void {
const className = identifierName(ngModule.type) !;
const rawImports = ngModule.rawImports ? [ngModule.rawImports] : [];
const rawExports = ngModule.rawExports ? [ngModule.rawExports] : [];
const injectorDefArg = mapLiteral({
'factory':
injectableCompiler.factoryFor({type: ngModule.type, symbol: ngModule.type.reference}, ctx),
'providers': convertMetaToOutput(ngModule.rawProviders, ctx),
'imports': convertMetaToOutput([...rawImports, ...rawExports], ctx),
});
const injectorDef = o.importExpr(R3.defineInjector).callFn([injectorDefArg]);
ctx.statements.push(new o.ClassStmt(
/* name */ className,
/* parent */ null,
/* fields */[new o.ClassField(
/* name */ 'ngInjectorDef',
/* type */ o.INFERRED_TYPE,
/* modifiers */[o.StmtModifier.Static],
/* initializer */ injectorDef, )],
/* getters */[],
/* constructorMethod */ new o.ClassMethod(null, [], []),
/* methods */[]));
}