Best JavaScript code snippet using stryker-parent
asts.js
Source:asts.js
1var no = require( 'nommon' );2var R = require( './runtime.js' );3// --------------------------------------------------------------------------------------------------------------- //4var teya = require( './teya.js' );5require( './types.js' );6var types = teya.types;7var TYPE = teya.types;8var entities = require( './entities.json' );9var internal_funcs = require( './internal_funcs.js' );10// --------------------------------------------------------------------------------------------------------------- //11function deentitify( s ) {12 return s13 .replace( /&#(\d+);?/g, function ( _, code ) {14 return String.fromCharCode( code );15 } )16 .replace( /&#[xX]([A-Fa-f0-9]+);?/g, function ( _, hex ) {17 return String.fromCharCode( parseInt( hex, 16 ) );18 } )19 .replace( /&(\w+);/g, function ( entity, name ) {20 return entities[ name ] || entity;21 } );22}23// # ASTs24// --------------------------------------------------------------------------------------------------------------- //25var asts = teya.asts = {};26// ÐдеÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ добавиÑÑ ÑÑо-нибÑÐ´Ñ Ð² базовÑй клаÑÑ.27// ÐапÑимеÑ, Ñак делаÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе ÑаблонÑ, генеÑÑÑие код.28//29asts.ast = {};30// ## Items31// --------------------------------------------------------------------------------------------------------------- //32asts.items = {};33asts.items._init = function() {34 this.items = [];35};36asts.items.add = function( item ) {37 this.items.push( item );38};39asts.items.is_empty = function() {40 return ( this.items.length === 0 );41};42asts.items.length = function() {43 return this.items.length;44};45asts.items.at = function( index, value ) {46 var items = this.items;47 if ( value !== undefined ) {48 items[ index ] = value;49 } else {50 return items[ index ];51 }52};53asts.items.for_each = function( callback ) {54 var items = this.items;55 for ( var i = 0, l = items.length; i < l; i++ ) {56 callback( items[ i ], i );57 }58};59// --------------------------------------------------------------------------------------------------------------- //60asts.items.starts_with_attr = function() {61 var items = this.items;62 if ( items.length === 0 ) {63 return false;64 }65 return items[ 0 ].starts_with_attr();66};67asts.items.closes_attrs = function() {68 var items = this.items;69 var R = false;70 for ( var i = 0, l = items.length; i < l; i++ ) {71 // FIXME: Ð ÑÑÑ Ð½Ðµ closes_attrs должно бÑÑÑ?!72 var r = items[ i ].closes_attrs();73 if ( r === true ) {74 return true;75 } else if ( r === undefined ) {76 R = undefined;77 }78 }79 return R;80};81asts.items.close_attrs = function( is_open, should_close ) {82 var type = this.get_type();83 if ( !( type === TYPE.XML || type === TYPE.ATTR ) ) {84 return;85 }86 var items = this.items;87 var _items = [];88 for ( var i = 0, l = items.length; i < l; i++ ) {89 var item = items[ i ];90 var type = item.get_type();91 if ( is_open ) {92 if ( type !== TYPE.ATTR ) {93 if ( item.starts_with_attr() === false ) {94 _items.push( this.child( 'close_attrs' ) );95 is_open = false;96 }97 item.close_attrs( is_open );98 }99 // FIXME: ÐеплоÑ
о Ð±Ñ Ð´ÐµÐ»Ð°ÑÑ warning, еÑли Ð¼Ñ Ð¾Ñевидно лиÑние вÑÑажениÑ100 // Ñ Ñипом `attr` вÑкинÑли.101 _items.push( item );102 } else {103 if ( type !== TYPE.ATTR ) {104 item.close_attrs( false );105 _items.push( item );106 }107 }108 }109 if ( should_close && is_open ) {110 _items.push( this.child( 'close_attrs' ) );111 }112 this.items = _items;113};114// --------------------------------------------------------------------------------------------------------------- //115asts.items.cast = function( to ) {116 to = to || this.get_type();117 // console.log( 'ITEMS.CAST', this.id, this.get_type(), to );118 var items = this.items;119 for ( var i = 0, l = items.length; i < l; i++ ) {120 var item = items[ i ];121 var from = item.get_type();122 if ( from === TYPE.NONE ) {123 continue;124 }125 if ( !types.is_castable( from, to ) ) {126 item.error( 'CAST_ERROR', {127 from: from,128 to: to129 } );130 }131 item.cast( to );132 }133};134/*135asts.items.oncast = function( to ) {136 var items = this.items;137 for ( var i = 0, l = items.length; i < l; i++ ) {138 items[ i ].cast( to );139 }140};141*/142// --------------------------------------------------------------------------------------------------------------- //143asts.items.string_children = function() {144 var r = [];145 var items = this.items;146 for ( var i = 0, l = items.length; i < l; i++ ) {147 r.push( items[ i ].to_string() );148 }149 return ( r.length ) ? r.join( '\n' ).replace( /^/gm, ' ' ) : '';150};151// --------------------------------------------------------------------------------------------------------------- //152asts.items._get_type = function() {153 var items = this.items;154 var l = items.length;155 if ( l === 0 ) { return TYPE.STRING; }156 var prev = items[ 0 ];157 var prev_type = prev.get_type();158 for ( var i = 1; i < l; i++ ) {159 var item = items[ i ];160 var type = item.get_type();161 var common_type = types.join_types( prev_type, type );162 if ( common_type === TYPE.UNDEF ) {163 item.error( 'WRONG_TYPES', {164 type_a: prev_type,165 id_a: prev.id,166 type_b: type,167 id_b: item.id168 } );169 }170 prev = item;171 prev_type = common_type;172 }173 return prev_type;174};175// --------------------------------------------------------------------------------------------------------------- //176asts.items.apply = function( callback, params ) {177 var items = this.items;178 for ( var i = 0, l = items.length; i < l; i++ ) {179 var item = items[ i ];180 callback( item, params );181 }182};183asts.items.dowalk = function( callback, params, pkey, pvalue ) {184 callback( this, params, pkey, pvalue );185 var items = this.items;186 for ( var i = 0, l = items.length; i < l; i++ ) {187 var item = items[ i ];188 item.dowalk( callback, params, i, this );189 }190};191asts.items.walkdo = function( callback, params, pkey, pvalue ) {192 var items = this.items;193 for ( var i = 0, l = items.length; i < l; i++ ) {194 var item = items[ i ];195 item.walkdo( callback, params, i, this );196 }197 callback( this, params, pkey, pvalue );198};199// --------------------------------------------------------------------------------------------------------------- //200asts.items.is_inline = function() {201 var items = this.items;202 var l = items.length;203 return ( l === 0 ) || ( l === 1 && items[ 0 ].is_inline() );204};205asts.items.is_const = function() {206 var items = this.items;207 for ( var i = 0, l = items.length; i < l; i++ ) {208 var item = items[ i ];209 if ( !item.is_const() ) {210 return false;211 }212 }213 return true;214};215// --------------------------------------------------------------------------------------------------------------- //216// --------------------------------------------------------------------------------------------------------------- //217// Q. Чем items оÑлиÑаÑÑÑÑ Ð¾Ñ collection?218//219// A. Тем, ÑÑо items -- ÑÑо вÑÑажение, напÑимеÑ, вÑе вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð² блоке,220// а collection ÑÑо пÑоÑÑо Ð½Ð°Ð±Ð¾Ñ Ñего-либо, напÑимеÑ, elses в if221// (ÑодеÑÐ¶Ð¸Ñ Ñнное колиÑеÑÑво else_if и, возможно, else).222//223asts.collection = {};224asts.collection.options = {225 base: 'items'226};227asts.collection.get_type = function() {228 return TYPE.NONE;229};230asts.collection.is_inline = function() {231 var items = this.items;232 switch ( items.length ) {233 case 0: return true;234 case 1: return items[ 0 ].is_inline();235 }236 return false;237};238// ## Module and block239// --------------------------------------------------------------------------------------------------------------- //240asts.module = {};241asts.module.options = {242 // NOTE: ТÑÑ Ð½ÐµÑ `contents`, Ñ
оÑÑ Ð¾Ð½Ð¸ и еÑÑÑ Ð² ast.243 props: 'vars funcs templates imports'244};245asts.module._init = function() {246 this.vars = this.ast( 'module_vars' );247 this.funcs = this.ast( 'module_funcs' );248 this.templates = this.ast( 'module_templates' );249 this.imports = this.ast( 'module_imports' );250};251asts.module.w_def = function() {252 var funcs = this.funcs;253 // FIXME: ÐеплоÑ
о Ð±Ñ ÑÑо делаÑÑ Ð¾Ð´Ð¸Ð½ Ñаз глобалÑно,254 // а не на каждÑй модÑлÑ.255 for ( var i = 0, l = internal_funcs.length; i < l; i++ ) {256 var func = this.child( 'def_internal_func', internal_funcs[ i ] );257 funcs.add( func );258 }259};260// --------------------------------------------------------------------------------------------------------------- //261asts.module_vars = {};262asts.module_vars.options = {263 mixin: 'collection'264};265asts.module_vars.teya__sep = '\n';266asts.module_vars.js__sep__init = '\n';267asts.module_vars.js__sep__export = '\n';268asts.module_vars.js__sep__list = ', ';269asts.module_vars.js__sep__def = '\n';270// --------------------------------------------------------------------------------------------------------------- //271asts.module_funcs = {};272asts.module_funcs.options = {273 mixin: 'collection'274};275asts.module_funcs.js__sep__define = '\n';276// --------------------------------------------------------------------------------------------------------------- //277asts.module_templates = {};278asts.module_templates.options = {279 mixin: 'collection'280};281asts.module_templates.teya__sep = '\n';282asts.module_templates.js__sep = '\n';283// --------------------------------------------------------------------------------------------------------------- //284asts.module_imports = {};285asts.module_imports.options = {286 mixin: 'collection'287};288asts.module_imports.teya__sep = '\n';289asts.module_imports.js__sep = '\n';290asts.module_imports.js__sep__init = '\n';291// --------------------------------------------------------------------------------------------------------------- //292asts.block = {};293asts.block.options = {294 props: 'params defs exprs',295 scope: true296};297asts.block._init = function() {298 this.params = this.ast( 'template_params' );299 this.defs = this.ast( 'block_defs' );300 this.exprs = this.ast( 'block_exprs' );301};302asts.block._get_type = function() {303 return this.exprs.get_type();304};305asts.block.oncast = function( to ) {306 this.exprs.cast( to );307};308asts.block.is_inline = function() {309 return this.params.is_empty() && this.defs.is_empty() && this.exprs.is_inline();310};311asts.block.starts_with_attr = function() {312 return this.exprs.starts_with_attr();313};314asts.block.closes_attrs = function() {315 return this.exprs.closes_attrs();316};317asts.block.close_attrs = function( is_open, should_close ) {318 this.exprs.close_attrs( is_open, should_close );319};320/*321asts.block.w_prepare = function() {322 if ( this.get_type() !== TYPE.XML && this.to_type !== TYPE.XML ) {323 return;324 }325 var items = this.exprs.items;326 var _items = [];327 var is_opened = ( this.parent.id === 'xml' );328 for ( var i = 0, l = items.length; i < l; i++ ) {329 var item = items[ i ];330 if ( item.get_type() !== TYPE.ATTR ) {331 if ( is_opened ) {332 _items.push( this.exprs.child( 'close_attrs' ) );333 is_opened = false;334 }335 } else {336 is_opened = true;337 }338 _items.push( item );339 }340 // FIXME: Ðожно ли ÑÑо ÑделаÑÑ ÐºÐ°Ðº-Ñо более ÑлеганÑно? Ðез `this.parent`?341 if ( is_opened && this.parent.id === 'xml' ) {342 _items.push( this.exprs.child( 'close_attrs' ) );343 }344 this.exprs.items = _items;345};346*/347// --------------------------------------------------------------------------------------------------------------- //348asts.block_defs = {};349asts.block_defs.options = {350 mixin: 'collection'351};352asts.block_defs.teya__sep = '\n';353asts.block_defs.js__sep__def = '\n';354// --------------------------------------------------------------------------------------------------------------- //355asts.block_exprs = {};356asts.block_exprs.options = {357 mixin: 'items'358};359asts.block_exprs.teya__sep = '\n\n';360asts.block_exprs.js__sep__output = '\n';361// --------------------------------------------------------------------------------------------------------------- //362/*363asts.block_params = {};364asts.block_params.options = {365 mixin: 'collection'366};367// --------------------------------------------------------------------------------------------------------------- //368asts.block_param = {};369asts.block_param.options = {370 props: 'name value'371};372asts.block_param._get_type = function() {373 return this.value.get_type();374};375asts.block_param.is_inline = function() {376 return this.value.is_inline();377};378asts.block_param.normalize_name = function() {379 return this.name.replace( /-/g, '_' );380};381*/382// ## Declarations383// --------------------------------------------------------------------------------------------------------------- //384asts.def = {};385// --------------------------------------------------------------------------------------------------------------- //386asts.def_template = {};387asts.def_template.options = {388 base: 'def',389 props: 'type name args body',390 scope: true391};392asts.def_template._get_type = function() {393 return this.type || this.body.get_type();394};395asts.def_template.w_def = function() {396 this.scope.root.add_template( this );397 this.tid = this.state.tid++;398};399asts.def_template.w_validate = function() {400 var type = this.get_type();401 if ( type === TYPE.ANY || type === TYPE.UNDEF ) {402 this.error( 'INVALID_RETURN_TYPE', { type: type } );403 }404};405asts.def_template.w_prepare = function() {406 this.body.cast( this.type );407 // FIXME: Рна ÑÑо ÑÑÑ Ð²Ð»Ð¸ÑÐµÑ true или false?408 this.body.close_attrs( true );409};410asts.def_template.starts_with_attr = function() {411 return this.body.starts_with_attr();412};413asts.def_template.normalize_name = function() {414 return this.name.replace( /[-\.]/g, '_' );415};416// --------------------------------------------------------------------------------------------------------------- //417asts.def_imported_template = {};418asts.def_imported_template.options = {419 props: 'name shortname'420};421asts.def_imported_template._init = function( params ) {422 this.namespace = params.namespace;423 this.def = params.def;424 this.import = params.import;425 this.shortname = this.def.name;426 this.name = ( this.namespace ) ? this.namespace + '.' + this.shortname : this.shortname;427};428asts.def_imported_template._get_type = function() {429 return this.def.get_type();430};431asts.def_imported_template.starts_with_attr = function() {432 return this.def.starts_with_attr();433};434asts.def_imported_template.normalize_name = function() {435 return this.name.replace( /[-\.]/g, '_' );436};437// --------------------------------------------------------------------------------------------------------------- //438asts.def_var = {};439asts.def_var.options = {440 base: 'def',441 props: 'name value'442};443asts.def_var.w_def = function() {444 var vars = this.scope.vars;445 var name = this.name;446 if ( vars[ name ] ) {447 this.error( 'VAR_REDEFINITION', { name: name } );448 }449 this.vid = this.state.vid++;450 this.is_user = true;451 vars[ name ] = this;452};453asts.def_var._get_type = function() {454 return this.value.get_type();455};456asts.def_var.w_prepare = function() {457 if ( !this.value.is_inline() ) {458 this.value.rid++;459 this.value.aid++;460 }461 this.value.cast();462};463asts.def_var.normalize_name = function() {464 return this.name.replace( /-/g, '_' );465};466asts.def_var.is_global = function() {467 return this.scope.is_global();468};469// --------------------------------------------------------------------------------------------------------------- //470asts.import = {};471asts.import.options = {472 props: 'filename namespace externals'473};474asts.import.w_def = function() {475 var filename = this.resolved_filename;476 if ( /\.teya$/.test( filename ) ) {477 var a_module = teya.parse( filename );478 var scope = this.scope.root;479 var namespace = this.namespace;480 var templates = a_module.templates.items;481 for ( var i = 0, l = templates.length; i < l; i++ ) {482 var template = templates[ i ];483 var proxy = template.child( 'def_imported_template', {484 namespace: namespace,485 def: template,486 import: this487 } );488 // СпеÑва добавлÑем Ñаблон в scope. ÐÑли он добавилÑÑ (Ñ.е. ÑÑо489 // не повÑоÑное добавление), Ñогда добавлÑем в ÑпиÑок Ñаблонов.490 //491 var added = scope.add_template( proxy );492 if ( added ) {493 this.root.templates.add( proxy );494 }495 }496 }497};498asts.import.w_action = function() {499 this.iid = this.state.iid++;500};501// --------------------------------------------------------------------------------------------------------------- //502asts.externals = {};503asts.externals.options = {504 base: 'collection'505};506// --------------------------------------------------------------------------------------------------------------- //507asts.def_func = {};508asts.def_func.options = {509 base: 'def',510 props: 'name args type body',511 scope: true512};513asts.def_func.w_def = function() {514 // FIXME: Ðожно ли ÑÑÑ Ð½Ð°Ð¿Ð¸ÑаÑÑ Ð¿ÑоÑÑо `this.scope.add_def_func( this )`?515 this.scope.root.add_def_func( this );516 this.fid = this.state.fid++;517 this.is_user = true;518};519asts.def_func.w_validate = function() {520 var type = this.get_type();521 if ( type === TYPE.ANY || type === TYPE.UNDEF ) {522 this.error( 'INVALID_RETURN_TYPE', { type: type } );523 }524};525asts.def_func._get_type = function() {526 if ( this.type ) {527 return this.type;528 }529 if ( this.__calc_type ) {530 this.error( 'UNTYPED_RECURSION' );531 }532 this.__calc_type = true;533 return this.body.get_type();534};535asts.def_func.w_prepare = function() {536 if ( this.body ) {537 this.body.cast();538 }539};540asts.def_func.get_full_name = function() {541 var full_name = this.__full_name;542 if ( !full_name ) {543 full_name = this.__full_name = this.name + '(' + this.get_signature() + ')';544 }545 return full_name;546};547asts.def_func.get_signature = function() {548 var signature = this.__signature;549 if ( !signature ) {550 signature = this.__signature = this.args.get_signature();551 }552 return signature;553};554asts.def_func.normalize_name = function() {555 return this.name.replace( /-/g, '_' );556};557asts.def_func.is_compatible_signature = function( inline_func_args ) {558 inline_func_args = inline_func_args.items;559 var args = this.args.items;560 var l1 = inline_func_args.length;561 var l2 = args.length;562 var last_arg = args[ l2 - 1 ];563 var rest_type;564 if ( last_arg ) {565 rest_type = types.is_rest( last_arg.get_type() );566 }567 if ( l1 > l2 && !rest_type ) {568 // ÐÑÑаемÑÑ Ð¿ÐµÑедаÑÑ Ð¿Ð°ÑамеÑÑов болÑÑе, Ñем опÑеделено.569 return false;570 }571 var i = 0;572 while ( i < l1 ) {573 var inline_func_arg = inline_func_args[ i ];574 var arg_type = '';575 if ( rest_type && i >= l2 - 1 ) {576 arg_type = rest_type;577 } else {578 var arg = args[ i ];579 if ( arg ) {580 arg_type = arg.get_type();581 }582 }583 if ( !( arg_type && types.is_castable( inline_func_arg.get_type(), arg_type ) ) ) {584 return false;585 }586 i++;587 }588 // ÐÑли в опÑеделении ÑÑнкÑии заÑвлено болÑÑе аÑгÑменÑов, Ñем пеÑедали,589 // Ñо вÑе лиÑние Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸Ð¼ÐµÑÑ Ð´ÐµÑолÑное знаÑение.590 //591 while ( i < l2 ) {592 var arg = args[ i ];593 if ( !arg.default ) {594 return false;595 }596 i++;597 }598 return true;599};600// --------------------------------------------------------------------------------------------------------------- //601asts.def_internal_func = {};602asts.def_internal_func.options = {603 base: 'def_func',604 props: 'name args type'605};606asts.def_internal_func._init = function( params ) {607 this.name = params.name;608 this.type = params.type;609 var arg_types = params.args;610 var args = this.args = this.child( 'def_args' );611 for ( var i = 0, l = arg_types.length; i < l; i++ ) {612 var arg_type = arg_types[ i ];613 var arg = args.child( 'def_arg', {614 type: arg_type615 } );616 args.add( arg );617 }618};619asts.def_internal_func.w_def = function() {620 // FIXME: Ðожно ли ÑÑÑ Ð½Ð°Ð¿Ð¸ÑаÑÑ Ð¿ÑоÑÑо `this.scope.add_def_func( this )`?621 this.scope.root.add_def_func( this );622 this.is_internal = true;623};624// --------------------------------------------------------------------------------------------------------------- //625asts.def_external_func = {};626asts.def_external_func.options = {627 base: 'def_internal_func'628};629asts.def_external_func.w_def = function() {630 // FIXME: Ðожно ли ÑÑÑ Ð½Ð°Ð¿Ð¸ÑаÑÑ Ð¿ÑоÑÑо `this.scope.add_def_func( this )`?631 this.scope.root.add_def_func( this );632 this.is_external = true;633};634// --------------------------------------------------------------------------------------------------------------- //635asts.def_args = {};636asts.def_args.options = {637 mixin: 'collection'638};639asts.def_args.teya__sep = ', ';640asts.def_args.js__sep__default = '\n';641asts.def_args.w_validate = function() {642 // Validation.643 // ÐÑовеÑÑем, ÑÑо поÑле паÑамеÑÑа Ñ Ð´ÐµÑолÑнÑм знаÑением,644 // вÑе оÑÑалÑнÑе паÑамеÑÑÑ Ñоже Ñ Ð´ÐµÑолÑнÑм знаÑением.645 var args = this.items;646 var has_default;647 for ( var i = 0, l = args.length; i < l; i++ ) {648 var arg = args[ i ];649 if ( has_default && !arg.default ) {650 arg.error( 'DEFAULT_VALUE_REQUIRED' );651 }652 if ( arg.default ) {653 has_default = true;654 }655 }656};657asts.def_args.index_of = function( name ) {658 var args = this.items;659 for ( var i = 0, l = args.length; i < l; i++ ) {660 var arg = args[ i ];661 if ( arg.name === name ) {662 return i;663 }664 }665 return -1;666};667asts.def_args.get_signature = function() {668 var signature = '';669 var args = this.items;670 for ( var i = 0, l = args.length; i < l; i++ ) {671 var arg = args[ i ];672 if ( i ) {673 signature += ',';674 }675 signature += arg.get_signature();676 }677 return signature;678};679// --------------------------------------------------------------------------------------------------------------- //680asts.def_arg = {};681asts.def_arg.options = {682 props: 'type name default'683};684asts.def_arg._init = function( params ) {685 if ( params ) {686 this.name = params.name;687 this.type = params.type;688 this.default = params.default;689 }690};691asts.def_arg.w_action = function() {692 if ( !this.type && !this.default ) {693 this.error( 'UNKNOWN_ARG_TYPE' );694 }695 var name = this.name;696 if ( name ) {697 var vars = this.scope.vars;698 if ( vars[ name ] ) {699 this.error( 'VAR_REDEFINITION', { name: name } );700 }701 this.vid = this.state.vid++;702 this.is_arg = true;703 vars[ name ] = this;704 }705};706asts.def_arg._get_type = function() {707 return this.type || this.default.get_type();708};709asts.def_arg.w_prepare = function() {710 if ( this.default ) {711 this.default.cast( this.get_type() );712 }713};714asts.def_arg.normalize_name = function() {715 return this.name.replace( /-/g, '_' );716};717asts.def_arg.get_signature = function() {718 return this.get_type();719};720// ## Expressions721// --------------------------------------------------------------------------------------------------------------- //722asts.expr = {};723// ### Block expressions724// --------------------------------------------------------------------------------------------------------------- //725asts.if = {};726asts.if.options = {727 base: 'expr',728 props: 'condition then elses'729};730asts.if._init = function() {731 this.elses = this.ast( 'elses' );732};733asts.if._get_type = function() {734 var type = this.then.get_type();735 var elses = this.elses.items;736 for ( var i = 0, l = elses.length; i < l; i++ ) {737 type = types.common_type( type, elses[ i ].get_type() );738 }739 return type;740};741asts.if.w_prepare = function() {742 this.condition.cast( TYPE.BOOLEAN );743 var elses = this.elses.items;744 for ( var i = 0, l = elses.length; i < l; i++ ) {745 var condition = elses[ i ].condition;746 if ( condition ) {747 condition.cast( TYPE.BOOLEAN );748 }749 }750};751asts.if.oncast = function( to ) {752 this.then.cast( to );753 this.elses.cast( to );754};755asts.if.is_inline = function() {756 return this.then.is_inline() && this.elses.is_inline();757};758asts.if.starts_with_attr = function() {759 return this.then.starts_with_attr() || this.elses.starts_with_attr();760};761asts.if.closes_attrs = function() {762 return this.then.closes_attrs() && this.elses.closes_attrs();763};764asts.if.close_attrs = function( is_open ) {765 this.then.close_attrs( is_open );766 this.elses.close_attrs( is_open );767};768// --------------------------------------------------------------------------------------------------------------- //769asts.elses = {};770asts.elses.options = {771 mixin: 'collection'772};773asts.elses.teya__sep = '\n';774asts.elses.js__sep__if_body = ' ';775// --------------------------------------------------------------------------------------------------------------- //776asts.else_if = {};777asts.else_if.options = {778 props: 'condition body'779};780asts.else_if._get_type = function() {781 return this.body.get_type();782};783// NOTE: is_inline === no.false784// ÐоÑÑомÑ, еÑли еÑÑÑ Ñ
оÑÑ Ð¾Ð´Ð¸Ð½ else if, Ñо if не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ is_inline.785asts.else_if.oncast = function( to ) {786 this.body.cast( to );787};788asts.else_if.starts_with_attr = function() {789 return this.body.starts_with_attr();790};791asts.else_if.closes_attrs = function() {792 return this.body.closes_attrs();793};794// --------------------------------------------------------------------------------------------------------------- //795asts.else = {};796asts.else.options = {797 props: 'body'798};799asts.else._get_type = function() {800 return this.body.get_type();801};802asts.else.is_inline = function() {803 return this.body.is_inline();804};805asts.else.oncast = function( to ) {806 this.body.cast( to );807};808asts.else.starts_with_attr = function() {809 return this.body.starts_with_attr();810};811asts.else.closes_attrs = function() {812 return this.body.closes_attrs();813};814// --------------------------------------------------------------------------------------------------------------- //815asts.for = {};816asts.for.options = {817 base: 'expr',818 props: 'selector body'819};820asts.for._get_type = function() {821 var type = this.body.get_type();822 return types.join_types( type, type );823};824asts.for.w_prepare = function() {825 this.body.xid++;826 this.body.cast( this.get_type() );827};828asts.for.starts_with_attr = function() {829 return this.body.starts_with_attr();830};831asts.for.closes_attrs = function() {832 return this.body.closes_attrs();833};834asts.for.close_attrs = function( is_open ) {835 this.body.close_attrs( is_open );836};837// --------------------------------------------------------------------------------------------------------------- //838asts.with = {};839asts.with.options = {840 base: 'expr',841 props: 'selector body'842};843asts.with._get_type = function() {844 return this.body.get_type();845};846asts.with.w_prepare = function() {847 this.body.cast( this.get_type() );848};849asts.with.is_inline = function() {850 return this.body.is_inline();851};852// --------------------------------------------------------------------------------------------------------------- //853asts.template = {};854asts.template.options = {855 base: 'expr',856 props: 'name params content'857};858asts.template._get_type = function() {859 // FIXME: ÐÐ¾Ð¶ÐµÑ Ð»Ð¸ ÑезÑлÑÑÐ°Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñаблона860 // бÑÑÑ Ð»Ñбого Ñипа? Ðли ÑолÑко, Ñкажем, xml и attr?861 //862 return this.def.get_type();863 /// return TYPE.XML;864};865asts.template.w_action = function() {866 var name = this.name;867 var def = this.scope.find_template( name );868 // NOTE: ÐажеÑÑÑ, не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ñак, ÑÑÐ¾Ð±Ñ def бÑл неопÑеделен.869 // ÐнаÑе ÑÑÐ¾Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¾Ñ Ð½Ðµ бÑÐ´ÐµÑ ÑÑиÑаÑÑÑÑ template,870 // а бÑÐ´ÐµÑ var.871 this.def = def;872 var inline_params = this.params;873 var block_params = this.content.params;874 var params = this.child( 'template_params' );875 var args = def.args;876 if ( args ) {877 var that = this;878 if ( inline_params ) {879 inline_params.for_each( function( param, i ) {880 var arg = args.at( i );881 if ( !arg ) {882 param.error( 'TOO_MANY_PARAMS' );883 }884 params.at( i, that.child( 'template_param', {885 name: arg.name,886 value: param.value,887 def: arg888 } ) );889 } );890 }891 block_params.for_each( function( param ) {892 name = param.name;893 var i = args.index_of( name );894 if ( i === -1 ) {895 param.error( 'NO_SUCH_ARGUMENT', { name: name } );896 }897 if ( params.at( i ) ) {898 param.error( 'PARAM_ALREADY_USED', { name: name } );899 }900 params.at( i, that.child( 'template_param', {901 name: name,902 value: param.value,903 def: args.at( i )904 } ) );905 } );906 args.for_each( function( arg, i ) {907 var param = params.at( i );908 if ( !param ) {909 params.at( i, that.child( 'template_param', {910 name: arg.name,911 value: null,912 def: arg913 } ) );914 }915 } );916 }917 this.params = params;918 this.content.params = null;919};920asts.template.w_prepare = function() {921 this.content.rid++;922 this.content.cast( TYPE.XML );923 this.params.for_each( function( param ) {924 if ( param.value ) {925 param.cast( param.def.get_type() );926 }927 } );928};929asts.template.close_attrs = function( is_open ) {930};931asts.template.starts_with_attr = function() {932 return this.def.starts_with_attr();933};934asts.template.normalize_name = function() {935 return this.name.replace( /[-\.]/g, '_' );936};937// --------------------------------------------------------------------------------------------------------------- //938/*939asts.inline_params = {};940asts.inline_params.options = {941 mixin: 'collection'942};943asts.inline_params.teya__sep = ', ';944asts.inline_param = {};945asts.inline_param.options = {946 props: 'name value'947};948asts.inline_param._get_type = function() {949 return this.value.get_type();950};951asts.inline_param.is_inline = no.true;952asts.inline_param.normalize_name = function() {953 return this.name.replace( /-/g, '_' );954};955*/956// --------------------------------------------------------------------------------------------------------------- //957asts.template_params = {};958asts.template_params.options = {959 mixin: 'collection'960};961asts.template_params.teya__sep = ', ';962// --------------------------------------------------------------------------------------------------------------- //963asts.template_param = {};964asts.template_param.options = {965 props: 'name value'966};967asts.template_param._init = function( params ) {968 if ( params ) {969 this.name = params.name;970 this.value = params.value;971 // FIXME: ТÑÑ Ð½ÐµÐ»ÑÐ·Ñ Ð¿ÑоÑÑо Ñак бÑаÑÑ Ð¸ копиÑоваÑÑ ÑÑÑлки. ÐÑжно делаÑÑ append,972 // Ñ Ð·Ð°Ð¼ÐµÐ½Ð¾Ð¹ parent'а и вÑего оÑÑалÑного. ÐÑжен ÑпеÑиалÑнÑй меÑод.973 // this.value.parent = this;974 this.def = params.def;975 }976};977asts.template_param._get_type = function() {978 var value = this.value;979 if ( value ) {980 return this.value.get_type();981 }982 return TYPE.NONE;983};984asts.template_param.is_inline = function() {985 if ( !this.value ) {986 return true;987 }988 return this.value.is_inline();989};990asts.template_param.normalize_name = function() {991 return this.name.replace( /-/g, '_' );992};993asts.template_param.w_prepare = function() {994 if ( this.value && !this.value.is_inline() ) {995 this.value.rid++;996 this.value.aid++;997 }998};999// --------------------------------------------------------------------------------------------------------------- //1000asts.value = {};1001asts.value.options = {1002 base: 'expr',1003 props: 'value'1004};1005asts.value._init = function( params ) {1006 this.value = params;1007};1008asts.value._get_type = function() {1009 return this.value.get_type();1010};1011asts.value.is_inline = function() {1012 return this.value.is_inline();1013};1014asts.value.oncast = function( to ) {1015 this.value.cast( to );1016};1017// FIXME: ÐÑделÑно нÑжно ÑÑиÑÑваÑÑ inline_expr.1018asts.value.starts_with_attr = function() {1019 return ( this.value.get_type() === TYPE.ATTR );1020};1021// FIXME: ÐÑделÑно нÑжно ÑÑиÑÑваÑÑ inline_expr.1022asts.value.closes_attrs = function() {1023 return ( this.value.get_type() !== TYPE.ATTR );1024};1025asts.value.close_attrs = no.op;1026// --------------------------------------------------------------------------------------------------------------- //1027asts.subexpr = {};1028asts.subexpr.options = {1029 base: 'expr',1030 props: 'body'1031};1032asts.subexpr._get_type = function() {1033 return this.body.get_type();1034};1035asts.subexpr.is_inline = function() {1036 this.body.is_inline();1037};1038asts.subexpr.oncast = function( to ) {1039 this.body.cast( to );1040};1041// --------------------------------------------------------------------------------------------------------------- //1042asts.array = {};1043asts.array.options = {1044 base: 'expr',1045 props: 'body'1046};1047asts.array._get_type = function() {1048 return TYPE.ARRAY;1049};1050asts.array.is_inline = function() {1051 return this.body.is_inline();1052};1053// --------------------------------------------------------------------------------------------------------------- //1054asts.object = {};1055asts.object.options = {1056 base: 'expr',1057 props: 'body'1058};1059asts.object._get_type = function() {1060 return TYPE.OBJECT;1061};1062asts.object.is_inline = function() {1063 return this.body.is_inline();1064};1065// --------------------------------------------------------------------------------------------------------------- //1066asts.pair = {};1067asts.pair.options = {1068 base: 'expr',1069 props: 'key value'1070};1071asts.pair._init = function( params ) {1072 this.key = params.key;1073 this.value = params.value;1074};1075asts.pair._get_type = function() {1076 return TYPE.PAIR;1077};1078asts.pair.w_prepare = function() {1079 this.value.rid++;1080 this.key.cast( TYPE.SCALAR );1081 this.value.cast();1082};1083asts.pair.is_inline = function() {1084 return this.value.is_inline();1085};1086// #### XML1087// --------------------------------------------------------------------------------------------------------------- //1088asts.xml = {};1089asts.xml.options = {1090 base: 'expr',1091 props: 'name xml_classes xml_id attrs content'1092};1093asts.xml._get_type = function() {1094 return TYPE.XML;1095};1096asts.xml.w_prepare = function() {1097 this.content.cast( TYPE.XML );1098 if ( !this.name.is_const() ) {1099 this.nid++;1100 this.name.cast( TYPE.STRING );1101 } else {1102 this.is_empty_tag = R.is_empty_tag( this.name.as_string() );1103 }1104 this.content.close_attrs(1105 this.content.starts_with_attr(),1106 // Флаг, говоÑÑÑий о Ñом, ÑÑо в ÑÑом блоке нÑжен вÑегда `close_attrs`.1107 true1108 );1109};1110asts.xml.starts_with_attr = no.false;1111asts.xml.closes_attrs = no.true;1112asts.xml.close_attrs = no.op;1113// --------------------------------------------------------------------------------------------------------------- //1114asts.xml_attrs = {};1115asts.xml_attrs.options = {1116 mixin: 'collection'1117};1118asts.xml_attrs.js__sep__inline = ' + ';1119asts.xml_attrs.js__sep__output = ',\n';1120// --------------------------------------------------------------------------------------------------------------- //1121asts.xml_attr = {};1122asts.xml_attr.options = {1123 base: 'expr',1124 props: 'name value'1125};1126asts.xml_attr._get_type = function() {1127 return TYPE.ATTR;1128};1129asts.xml_attr.w_prepare = function() {1130 // FIXME: ТÑÑ Ð´Ð¾Ð»Ð¶Ð½Ð¾ бÑÑÑ attrvalue?1131 this.value.cast( TYPE.STRING );1132};1133// --------------------------------------------------------------------------------------------------------------- //1134asts.xml_classes = {};1135asts.xml_classes.options = {1136 mixin: 'collection'1137};1138asts.xml_class = {};1139asts.xml_class.options = {1140 props: 'value'1141};1142asts.xml_id = {};1143asts.xml_id.options = {1144 props: 'value'1145};1146// --------------------------------------------------------------------------------------------------------------- //1147asts.attr = {};1148asts.attr.options = {1149 base: 'expr',1150 props: 'name value'1151};1152asts.attr._get_type = function() {1153 return TYPE.ATTR;1154};1155asts.attr.w_prepare = function() {1156 var type = this.value.get_type();1157 if ( type === TYPE.OBJECT || type === TYPE.ARRAY ) {1158 this.value.cast( TYPE.JSON );1159 } else {1160 this.value.cast( TYPE.STRING );1161 }1162 if ( !this.value.is_inline() ) {1163 this.value.rid++;1164 }1165};1166asts.attr.starts_with_attr = no.true;1167asts.attr.closes_attrs = no.false;1168asts.attr.close_attrs = no.op;1169// --------------------------------------------------------------------------------------------------------------- //1170asts.param_content = {};1171asts.param_content.options = {1172 base: 'expr'1173};1174asts.param_content._get_type = function() {1175 return TYPE.XML;1176};1177asts.param_content.starts_with_attr = no.op;1178asts.param_content.close_attrs = no.op;1179// --------------------------------------------------------------------------------------------------------------- //1180asts.param_content_attrs = {};1181asts.param_content_attrs.options = {1182 base: 'expr'1183};1184asts.param_content_attrs._get_type = function() {1185 return TYPE.ATTR;1186};1187asts.param_content_attrs.starts_with_attr = no.true;1188asts.param_content_attrs.close_attrs = no.op;1189// --------------------------------------------------------------------------------------------------------------- //1190asts.param_content_other = {};1191asts.param_content_other.options = {1192 base: 'expr'1193};1194asts.param_content_other._get_type = function() {1195 return TYPE.XML;1196};1197asts.param_content_other.starts_with_attr = no.false;1198asts.param_content_other.close_attrs = no.op;1199// ### Inline expressions1200// --------------------------------------------------------------------------------------------------------------- //1201asts.inline_expr = {};1202asts.inline_expr.is_inline = no.true;1203// #### Binary operators1204// --------------------------------------------------------------------------------------------------------------- //1205asts.inline_binop = {};1206asts.inline_binop.options = {1207 base: 'inline_expr',1208 props: 'left op right'1209};1210// --------------------------------------------------------------------------------------------------------------- //1211asts.inline_or = {};1212asts.inline_or.options = {1213 base: 'inline_binop'1214};1215asts.inline_or._get_type = function() {1216 // ÐоÑÐµÐ¼Ñ ÑÑÑ Ð±ÐµÑеÑÑÑ Ñип пÑавого аÑгÑменÑа?1217 // ÐоÑÐ¾Ð¼Ñ ÑÑо, еÑли левÑй аÑгÑÐ¼ÐµÐ½Ñ Ð»Ð¾Ð¶ÐµÐ½, Ñо Ð¼Ñ Ð¿Ð¾Ð»ÑÑим пÑавÑй аÑгÑменÑ.1218 // ÐÑли же он иÑÑинен, Ñо как минимÑм должен пÑиводиÑÑÑÑ Ðº ÑÐ¸Ð¿Ñ Ð¿Ñавого аÑгÑменÑа.1219 //1220 return this.right.get_type();1221};1222asts.inline_or.w_prepare = function() {1223 var type = this.get_type();1224 this.left.cast( type );1225 this.right.cast( type );1226};1227// --------------------------------------------------------------------------------------------------------------- //1228asts.inline_and = {};1229asts.inline_and.options = {1230 base: 'inline_binop'1231};1232asts.inline_and._get_type = function() {1233 // См. комменÑаÑии к inline_or._get_type.1234 //1235 return this.right.get_type();1236};1237asts.inline_and.w_prepare = function() {1238 var type = this.get_type();1239 this.left.cast( type );1240 this.right.cast( type );1241};1242// --------------------------------------------------------------------------------------------------------------- //1243asts.inline_eq = {};1244asts.inline_eq.options = {1245 base: 'inline_binop'1246};1247asts.inline_eq._get_type = function() {1248 return TYPE.BOOLEAN;1249};1250asts.inline_eq.w_prepare = function() {1251 var left = this.left;1252 var right = this.right;1253 var left_type = left.get_type();1254 var right_type = right.get_type();1255 if ( left === TYPE.BOOLEAN || right === TYPE.BOOLEAN ) {1256 left.cast( TYPE.BOOLEAN );1257 right.cast( TYPE.BOOLEAN );1258 } else {1259 left.cast( TYPE.SCALAR );1260 right.cast( TYPE.SCALAR );1261 }1262};1263// --------------------------------------------------------------------------------------------------------------- //1264asts.inline_rel = {};1265asts.inline_rel.options = {1266 base: 'inline_binop'1267};1268asts.inline_rel._get_type = function() {1269 return TYPE.BOOLEAN;1270};1271asts.inline_rel.w_prepare = function() {1272 this.left.cast( TYPE.SCALAR );1273 this.right.cast( TYPE.SCALAR );1274};1275// --------------------------------------------------------------------------------------------------------------- //1276asts.inline_add = {};1277asts.inline_add.options = {1278 base: 'inline_binop'1279};1280asts.inline_add._get_type = function() {1281 return TYPE.NUMBER;1282};1283asts.inline_add.w_prepare = function() {1284 this.left.cast( TYPE.NUMBER );1285 this.right.cast( TYPE.NUMBER );1286};1287// --------------------------------------------------------------------------------------------------------------- //1288asts.inline_mul = {};1289asts.inline_mul.options = {1290 base: 'inline_binop'1291};1292asts.inline_mul._get_type = function() {1293 return TYPE.NUMBER;1294};1295asts.inline_mul.w_prepare = function() {1296 this.left.cast( TYPE.NUMBER );1297 this.right.cast( TYPE.NUMBER );1298};1299// --------------------------------------------------------------------------------------------------------------- //1300// FIXME: ÐодÑмаÑÑ ÐµÑе, а нÑжен ли ÑÑÐ¾Ñ Ð¾Ð¿ÐµÑаÑоÑ?1301//1302asts.inline_union = {};1303asts.inline_union.options = {1304 base: 'inline_binop'1305};1306asts.inline_union._get_type = function() {1307 return TYPE.ARRAY;1308};1309asts.inline_union.w_prepare = function() {1310 this.left.cast( TYPE.ARRAY );1311 this.right.cast( TYPE.ARRAY );1312};1313// #### Unary operators1314// --------------------------------------------------------------------------------------------------------------- //1315asts.inline_unop = {};1316asts.inline_unop.options = {1317 base: 'inline_expr',1318 props: 'left op'1319};1320// --------------------------------------------------------------------------------------------------------------- //1321asts.inline_unary = {};1322asts.inline_unary.options = {1323 base: 'inline_unop'1324};1325asts.inline_unary._get_type = function() {1326 return TYPE.NUMBER;1327};1328asts.inline_unary.w_prepare = function() {1329 this.left.cast( TYPE.NUMBER );1330};1331// --------------------------------------------------------------------------------------------------------------- //1332asts.inline_not = {};1333asts.inline_not.options = {1334 base: 'inline_unop'1335};1336asts.inline_not._get_type = function() {1337 return TYPE.BOOLEAN;1338};1339asts.inline_not.w_prepare = function() {1340 this.left.cast( TYPE.BOOLEAN );1341};1342// #### Inline primaries1343// --------------------------------------------------------------------------------------------------------------- //1344asts.true = {};1345asts.true.options = {1346 base: 'inline_expr'1347};1348asts.true._get_type = function() {1349 return TYPE.BOOLEAN;1350};1351asts.false = {};1352asts.false.options = {1353 base: 'inline_expr'1354};1355asts.false._get_type = function() {1356 return TYPE.BOOLEAN;1357};1358// --------------------------------------------------------------------------------------------------------------- //1359asts.inline_number = {};1360asts.inline_number.options = {1361 base: 'inline_expr',1362 props: 'value'1363};1364asts.inline_number._get_type = function() {1365 return TYPE.NUMBER;1366};1367asts.inline_number.is_const = no.true;1368// --------------------------------------------------------------------------------------------------------------- //1369asts.inline_subexpr = {};1370asts.inline_subexpr.options = {1371 base: 'inline_expr',1372 props: 'expr'1373};1374asts.inline_subexpr._get_type = function() {1375 return this.expr.get_type();1376};1377// --------------------------------------------------------------------------------------------------------------- //1378asts.inline_var = {};1379asts.inline_var.options = {1380 base: 'inline_expr',1381 props: 'name'1382};1383asts.inline_var.w_action = function() {1384 var name = this.name;1385 var def = this.scope.find_var( name );1386 if ( !def ) {1387 this.error( 'UNDEFINED_VAR', { name: name } );1388 }1389 this.def = def;1390};1391asts.inline_var._get_type = function() {1392 return this.def.get_type();1393};1394asts.inline_var.is_global = function() {1395 return this.def.is_global();1396};1397// --------------------------------------------------------------------------------------------------------------- //1398asts.inline_func = {};1399asts.inline_func.options = {1400 base: 'inline_expr',1401 props: 'name args'1402};1403asts.inline_func._get_type = function() {1404 return this.def.get_type();1405};1406asts.inline_func.w_action = function() {1407 // var name = this.name;1408 var def = this.scope.find_def_func( this );1409 // if ( !def ) {1410 // this.error( 'UNDEFINED_FUNC', { name: name } );1411 // }1412 this.def = def;1413};1414asts.inline_func.w_prepare = function() {1415 var def_args = this.def.args;1416 var args = this.args;1417 var rest_type;1418 this.args.for_each( function( arg, i ) {1419 var def_arg = def_args.at( i );1420 if ( !def_arg && !rest_type ) {1421 arg.error( 'ARG_NOT_DEFINED' );1422 }1423 var type;1424 if ( !rest_type ) {1425 type = def_arg.get_type();1426 rest_type = types.is_rest( type );1427 }1428 arg.value.cast( rest_type || type );1429 } );1430};1431// --------------------------------------------------------------------------------------------------------------- //1432asts.inline_func_args = {};1433asts.inline_func_args.options = {1434 mixin: 'collection'1435};1436asts.inline_func_args.teya__sep = ', ';1437asts.inline_func_args.js__sep = ', ';1438asts.inline_func_arg = {};1439asts.inline_func_arg.options = {1440 props: 'name value'1441};1442asts.inline_func_arg._get_type = function() {1443 return this.value.get_type();1444};1445// --------------------------------------------------------------------------------------------------------------- //1446asts.inline_ternary = {};1447asts.inline_ternary.options = {1448 base: 'inline_expr',1449 props: 'condition then else'1450};1451asts.inline_ternary._get_type = function() {1452 return types.common_type( this.then.get_type(), this.else.get_type() );1453};1454// ##### Inline stirng1455// --------------------------------------------------------------------------------------------------------------- //1456asts.inline_string = {};1457asts.inline_string.options = {1458 base: 'inline_expr',1459 props: 'value'1460};1461asts.inline_string._get_type = function() {1462 return TYPE.STRING;1463};1464asts.inline_string.oncast = function( to ) {1465 this.value.cast( to );1466};1467asts.inline_string.as_string = function() {1468 return this.value.as_string();1469};1470// --------------------------------------------------------------------------------------------------------------- //1471asts.string_content = {};1472asts.string_content.options = {1473 mixin: 'collection'1474};1475asts.string_content.teya__sep = '';1476asts.string_content.js__sep__cast = ' + ';1477asts.string_content.as_string = function() {1478 var items = this.items;1479 // FIXME: РабоÑÐ°ÐµÑ ÑолÑко, еÑли Ñам конÑÑанÑÐ½Ð°Ñ ÑÑÑока.1480 return items[ 0 ].value;1481};1482// --------------------------------------------------------------------------------------------------------------- //1483asts.string_expr = {};1484asts.string_expr.options = {1485 base: 'inline_expr',1486 props: 'expr'1487};1488asts.string_expr._get_type = function() {1489 return this.expr.get_type();1490};1491// --------------------------------------------------------------------------------------------------------------- //1492asts.string_literal = {};1493asts.string_literal.options = {1494 base: 'inline_expr',1495 props: 'value'1496};1497asts.string_literal._get_type = function() {1498 return TYPE.STRING;1499};1500asts.string_literal.w_action = function() {1501 this.value = deentitify( this.value );1502};1503asts.string_literal.stringify = function() {1504 var to_type = this.to_type;1505 // FIXME: СделаÑÑ ÐºÐ°ÐºÐ¾Ð¹-Ñо types.need_cast.1506 var value = ( to_type && to_type !== TYPE.ANY ) ? R[ 'to_' + to_type ]( this.value ) : this.value;1507 return value1508 .replace( /"/g, '\\"', 'g' )1509 .replace( /'/g, "\\'", 'g' )1510 .replace( /\n/g, '\\n', 'g' );1511};1512asts.string_literal.is_const = no.true;1513// #### JPath1514// --------------------------------------------------------------------------------------------------------------- //1515asts.jpath = {};1516asts.jpath.options = {1517 base: 'inline_expr',1518 props: 'abs steps in_context'1519};1520asts.jpath._get_type = function() {1521 return TYPE.JSON;1522};1523// --------------------------------------------------------------------------------------------------------------- //1524asts.jpath_steps = {};1525asts.jpath_steps.options = {1526 mixin: 'collection'1527};1528asts.jpath_steps.teya__sep = '';1529// --------------------------------------------------------------------------------------------------------------- //1530asts.jpath_nametest = {};1531asts.jpath_nametest.options = {1532 props: 'name'1533};1534// --------------------------------------------------------------------------------------------------------------- //1535asts.jpath_predicate = {};1536asts.jpath_predicate.options = {1537 props: 'expr'1538};1539// --------------------------------------------------------------------------------------------------------------- //1540asts.jpath_filter = {};1541asts.jpath_filter.options = {1542 base: 'inline_expr',1543 props: 'jpath expr'1544};1545asts.jpath_filter._get_type = function() {1546 return TYPE.JSON;1547};1548asts.jpath_filter.w_prepare = function() {1549 this.expr.cast( TYPE.JSON );1550};1551// #### Inline misc1552// --------------------------------------------------------------------------------------------------------------- //1553asts.inline_object = {};1554asts.inline_object.options = {1555 base: 'inline_expr',1556 props: 'body'1557};1558asts.inline_object._get_type = function() {1559 return TYPE.OBJECT;1560};1561// --------------------------------------------------------------------------------------------------------------- //1562asts.inline_pairs = {};1563asts.inline_pairs.options = {1564 mixin: 'items'1565};1566asts.inline_pairs.teya__sep = ', ';1567asts.inline_pairs.js__sep__output = '\n';1568asts.inline_pairs.js__sep__value = ', ';1569asts.inline_pairs.is_inline = no.true;1570// --------------------------------------------------------------------------------------------------------------- //1571asts.inline_pair = {};1572asts.inline_pair.options = {1573 props: 'key value'1574};1575asts.inline_pair._init = function( params ) {1576 if ( params ) {1577 this.key = params.key;1578 this.value = params.value;1579 }1580};1581asts.inline_pair._get_type = function() {1582 return TYPE.PAIR;1583};1584asts.inline_pair.w_prepare = function() {1585 this.key.cast( TYPE.SCALAR );1586 this.value.cast();1587};1588asts.inline_pair.is_inline = no.true;1589// --------------------------------------------------------------------------------------------------------------- //1590asts.inline_array = {};1591asts.inline_array.options = {1592 base: 'inline_expr',1593 props: 'body'1594};1595asts.inline_array._get_type = function() {1596 return TYPE.ARRAY;1597};1598// --------------------------------------------------------------------------------------------------------------- //1599asts.inline_items = {};1600asts.inline_items.options = {1601 mixin: 'items'1602};1603asts.inline_items.teya__sep = ', ';1604asts.inline_items.js__sep__output = '\n';1605asts.inline_items.js__sep__value = ', ';1606asts.inline_items.is_inline = function() {1607 return true;1608};1609// --------------------------------------------------------------------------------------------------------------- //1610asts.inline_item = {};1611asts.inline_item.options = {1612 props: 'value'1613};1614asts.inline_item._init = function( params ) {1615 this.value = params;1616};1617asts.inline_item._get_type = function() {1618 return TYPE.ITEM;1619};1620asts.inline_item.is_inline = no.true;1621// --------------------------------------------------------------------------------------------------------------- //1622asts.close_attrs = {};1623asts.close_attrs.options = {1624};1625asts.close_attrs._get_type = function() {1626 return TYPE.XML;1627};1628asts.close_attrs.starts_with_attr = no.false;1629asts.close_attrs.closes_attrs = no.true;1630asts.close_attrs.close_attrs = no.op;1631// --------------------------------------------------------------------------------------------------------------- //1632// ÐобавлÑем кодогенеÑаÑиÑ.1633require( '../templates/compiled/teya.js' )( asts );1634require( '../templates/compiled/js.js' )( asts );1635// --------------------------------------------------------------------------------------------------------------- //1636module.exports = asts;...
parserRealSource14.js
Source:parserRealSource14.js
1//// [parserRealSource14.ts]2// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0. 3// See LICENSE.txt in the project root for complete license information.4///<reference path='typescript.ts' />5module TypeScript {6 export function lastOf(items: any[]): any {7 return (items === null || items.length === 0) ? null : items[items.length - 1];8 }9 export function max(a: number, b: number): number {10 return a >= b ? a : b;11 }12 export function min(a: number, b: number): number {13 return a <= b ? a : b;14 }15 //16 // Helper class representing a path from a root ast node to a (grand)child ast node.17 // This is helpful as our tree don't have parents.18 //19 export class AstPath {20 public asts: TypeScript.AST[] = [];21 public top: number = -1;22 static reverseIndexOf(items: any[], index: number): any {23 return (items === null || items.length <= index) ? null : items[items.length - index - 1];24 }25 public clone(): AstPath {26 var clone = new AstPath();27 clone.asts = this.asts.map((value) => { return value; });28 clone.top = this.top;29 return clone;30 }31 public pop(): TypeScript.AST {32 var head = this.ast();33 this.up();34 while (this.asts.length > this.count()) {35 this.asts.pop();36 }37 return head;38 }39 public push(ast: TypeScript.AST) {40 while (this.asts.length > this.count()) {41 this.asts.pop();42 }43 this.top = this.asts.length;44 this.asts.push(ast);45 }46 public up() {47 if (this.top <= -1)48 throw new Error("Invalid call to 'up'");49 this.top--;50 }51 public down() {52 if (this.top == this.ast.length - 1)53 throw new Error("Invalid call to 'down'");54 this.top++;55 }56 public nodeType(): TypeScript.NodeType {57 if (this.ast() == null)58 return TypeScript.NodeType.None;59 return this.ast().nodeType;60 }61 public ast() {62 return <TypeScript.AST>AstPath.reverseIndexOf(this.asts, this.asts.length - (this.top + 1));63 }64 public parent() {65 return <TypeScript.AST>AstPath.reverseIndexOf(this.asts, this.asts.length - this.top);66 }67 public count() {68 return this.top + 1;69 }70 public get(index: number): TypeScript.AST {71 return this.asts[index];72 }73 public isNameOfClass(): boolean {74 if (this.ast() === null || this.parent() === null)75 return false;76 return (this.ast().nodeType === TypeScript.NodeType.Name) &&77 (this.parent().nodeType === TypeScript.NodeType.ClassDeclaration) &&78 ((<TypeScript.InterfaceDeclaration>this.parent()).name === this.ast());79 }80 public isNameOfInterface(): boolean {81 if (this.ast() === null || this.parent() === null)82 return false;83 return (this.ast().nodeType === TypeScript.NodeType.Name) &&84 (this.parent().nodeType === TypeScript.NodeType.InterfaceDeclaration) &&85 ((<TypeScript.InterfaceDeclaration>this.parent()).name === this.ast());86 }87 public isNameOfArgument(): boolean {88 if (this.ast() === null || this.parent() === null)89 return false;90 return (this.ast().nodeType === TypeScript.NodeType.Name) &&91 (this.parent().nodeType === TypeScript.NodeType.ArgDecl) &&92 ((<TypeScript.ArgDecl>this.parent()).id === this.ast());93 }94 public isNameOfVariable(): boolean {95 if (this.ast() === null || this.parent() === null)96 return false;97 return (this.ast().nodeType === TypeScript.NodeType.Name) &&98 (this.parent().nodeType === TypeScript.NodeType.VarDecl) &&99 ((<TypeScript.VarDecl>this.parent()).id === this.ast());100 }101 public isNameOfModule(): boolean {102 if (this.ast() === null || this.parent() === null)103 return false;104 return (this.ast().nodeType === TypeScript.NodeType.Name) &&105 (this.parent().nodeType === TypeScript.NodeType.ModuleDeclaration) &&106 ((<TypeScript.ModuleDeclaration>this.parent()).name === this.ast());107 }108 public isNameOfFunction(): boolean {109 if (this.ast() === null || this.parent() === null)110 return false;111 return (this.ast().nodeType === TypeScript.NodeType.Name) &&112 (this.parent().nodeType === TypeScript.NodeType.FuncDecl) &&113 ((<TypeScript.FuncDecl>this.parent()).name === this.ast());114 }115 public isChildOfScript(): boolean {116 var ast = lastOf(this.asts);117 return this.count() >= 3 &&118 this.asts[this.top] === ast &&119 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&120 this.asts[this.top - 2].nodeType === TypeScript.NodeType.Script;121 }122 public isChildOfModule(): boolean {123 var ast = lastOf(this.asts);124 return this.count() >= 3 &&125 this.asts[this.top] === ast &&126 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&127 this.asts[this.top - 2].nodeType === TypeScript.NodeType.ModuleDeclaration;128 }129 public isChildOfClass(): boolean {130 var ast = lastOf(this.asts);131 return this.count() >= 3 &&132 this.asts[this.top] === ast &&133 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&134 this.asts[this.top - 2].nodeType === TypeScript.NodeType.ClassDeclaration;135 }136 public isArgumentOfClassConstructor(): boolean {137 var ast = lastOf(this.asts);138 return this.count() >= 5 &&139 this.asts[this.top] === ast &&140 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&141 this.asts[this.top - 2].nodeType === TypeScript.NodeType.FuncDecl &&142 this.asts[this.top - 3].nodeType === TypeScript.NodeType.List &&143 this.asts[this.top - 4].nodeType === TypeScript.NodeType.ClassDeclaration &&144 ((<TypeScript.FuncDecl>this.asts[this.top - 2]).isConstructor) &&145 ((<TypeScript.FuncDecl>this.asts[this.top - 2]).arguments === this.asts[this.top - 1]) &&146 ((<TypeScript.ClassDeclaration>this.asts[this.top - 4]).constructorDecl === this.asts[this.top - 2]);147 }148 public isChildOfInterface(): boolean {149 var ast = lastOf(this.asts);150 return this.count() >= 3 &&151 this.asts[this.top] === ast &&152 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&153 this.asts[this.top - 2].nodeType === TypeScript.NodeType.InterfaceDeclaration;154 }155 public isTopLevelImplicitModule() {156 return this.count() >= 1 &&157 this.asts[this.top].nodeType === TypeScript.NodeType.ModuleDeclaration &&158 TypeScript.hasFlag((<TypeScript.ModuleDeclaration>this.asts[this.top]).modFlags, TypeScript.ModuleFlags.IsWholeFile);159 }160 public isBodyOfTopLevelImplicitModule() {161 return this.count() >= 2 &&162 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&163 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ModuleDeclaration &&164 (<TypeScript.ModuleDeclaration>this.asts[this.top - 1]).members == this.asts[this.top - 0] &&165 TypeScript.hasFlag((<TypeScript.ModuleDeclaration>this.asts[this.top - 1]).modFlags, TypeScript.ModuleFlags.IsWholeFile);166 }167 public isBodyOfScript(): boolean {168 return this.count() >= 2 &&169 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Script &&170 (<TypeScript.Script>this.asts[this.top - 1]).bod == this.asts[this.top - 0];171 }172 public isBodyOfSwitch(): boolean {173 return this.count() >= 2 &&174 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Switch &&175 (<TypeScript.SwitchStatement>this.asts[this.top - 1]).caseList == this.asts[this.top - 0];176 }177 public isBodyOfModule(): boolean {178 return this.count() >= 2 &&179 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ModuleDeclaration &&180 (<TypeScript.ModuleDeclaration>this.asts[this.top - 1]).members == this.asts[this.top - 0];181 }182 public isBodyOfClass(): boolean {183 return this.count() >= 2 &&184 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ClassDeclaration &&185 (<TypeScript.ClassDeclaration>this.asts[this.top - 1]).members == this.asts[this.top - 0];186 }187 public isBodyOfFunction(): boolean {188 return this.count() >= 2 &&189 this.asts[this.top - 1].nodeType === TypeScript.NodeType.FuncDecl &&190 (<TypeScript.FuncDecl>this.asts[this.top - 1]).bod == this.asts[this.top - 0];191 }192 public isBodyOfInterface(): boolean {193 return this.count() >= 2 &&194 this.asts[this.top - 1].nodeType === TypeScript.NodeType.InterfaceDeclaration &&195 (<TypeScript.InterfaceDeclaration>this.asts[this.top - 1]).members == this.asts[this.top - 0];196 }197 public isBodyOfBlock(): boolean {198 return this.count() >= 2 &&199 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Block &&200 (<TypeScript.Block>this.asts[this.top - 1]).statements == this.asts[this.top - 0];201 }202 public isBodyOfFor(): boolean {203 return this.count() >= 2 &&204 this.asts[this.top - 1].nodeType === TypeScript.NodeType.For &&205 (<TypeScript.ForStatement>this.asts[this.top - 1]).body == this.asts[this.top - 0];206 }207 public isBodyOfCase(): boolean {208 return this.count() >= 2 &&209 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Case &&210 (<TypeScript.CaseStatement>this.asts[this.top - 1]).body == this.asts[this.top - 0];211 }212 public isBodyOfTry(): boolean {213 return this.count() >= 2 &&214 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Try &&215 (<TypeScript.Try>this.asts[this.top - 1]).body == this.asts[this.top - 0];216 }217 public isBodyOfCatch(): boolean {218 return this.count() >= 2 &&219 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Catch &&220 (<TypeScript.Catch>this.asts[this.top - 1]).body == this.asts[this.top - 0];221 }222 public isBodyOfDoWhile(): boolean {223 return this.count() >= 2 &&224 this.asts[this.top - 1].nodeType === TypeScript.NodeType.DoWhile &&225 (<TypeScript.DoWhileStatement>this.asts[this.top - 1]).body == this.asts[this.top - 0];226 }227 public isBodyOfWhile(): boolean {228 return this.count() >= 2 &&229 this.asts[this.top - 1].nodeType === TypeScript.NodeType.While &&230 (<TypeScript.WhileStatement>this.asts[this.top - 1]).body == this.asts[this.top - 0];231 }232 public isBodyOfForIn(): boolean {233 return this.count() >= 2 &&234 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ForIn &&235 (<TypeScript.ForInStatement>this.asts[this.top - 1]).body == this.asts[this.top - 0];236 }237 public isBodyOfWith(): boolean {238 return this.count() >= 2 &&239 this.asts[this.top - 1].nodeType === TypeScript.NodeType.With &&240 (<TypeScript.WithStatement>this.asts[this.top - 1]).body == this.asts[this.top - 0];241 }242 public isBodyOfFinally(): boolean {243 return this.count() >= 2 &&244 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Finally &&245 (<TypeScript.Finally>this.asts[this.top - 1]).body == this.asts[this.top - 0];246 }247 public isCaseOfSwitch(): boolean {248 return this.count() >= 3 &&249 this.asts[this.top - 2].nodeType === TypeScript.NodeType.Switch &&250 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&251 (<TypeScript.SwitchStatement>this.asts[this.top - 2]).caseList == this.asts[this.top - 1];252 }253 public isDefaultCaseOfSwitch(): boolean {254 return this.count() >= 3 &&255 this.asts[this.top - 2].nodeType === TypeScript.NodeType.Switch &&256 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&257 (<TypeScript.SwitchStatement>this.asts[this.top - 2]).caseList == this.asts[this.top - 1] &&258 (<TypeScript.SwitchStatement>this.asts[this.top - 2]).defaultCase == this.asts[this.top - 0];259 }260 public isListOfObjectLit(): boolean {261 return this.count() >= 2 &&262 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ObjectLit &&263 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&264 (<TypeScript.UnaryExpression>this.asts[this.top - 1]).operand == this.asts[this.top - 0];265 }266 public isBodyOfObjectLit(): boolean {267 return this.isListOfObjectLit();268 }269 public isEmptyListOfObjectLit(): boolean {270 return this.count() >= 2 &&271 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ObjectLit &&272 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&273 (<TypeScript.UnaryExpression>this.asts[this.top - 1]).operand == this.asts[this.top - 0] &&274 (<TypeScript.ASTList>this.asts[this.top - 0]).members.length == 0;275 }276 public isMemberOfObjectLit(): boolean {277 return this.count() >= 3 &&278 this.asts[this.top - 2].nodeType === TypeScript.NodeType.ObjectLit &&279 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&280 this.asts[this.top - 0].nodeType === TypeScript.NodeType.Member &&281 (<TypeScript.UnaryExpression>this.asts[this.top - 2]).operand == this.asts[this.top - 1];282 }283 public isNameOfMemberOfObjectLit(): boolean {284 return this.count() >= 4 &&285 this.asts[this.top - 3].nodeType === TypeScript.NodeType.ObjectLit &&286 this.asts[this.top - 2].nodeType === TypeScript.NodeType.List &&287 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Member &&288 this.asts[this.top - 0].nodeType === TypeScript.NodeType.Name &&289 (<TypeScript.UnaryExpression>this.asts[this.top - 3]).operand == this.asts[this.top - 2];290 }291 public isListOfArrayLit(): boolean {292 return this.count() >= 2 &&293 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ArrayLit &&294 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&295 (<TypeScript.UnaryExpression>this.asts[this.top - 1]).operand == this.asts[this.top - 0];296 }297 public isTargetOfMember(): boolean {298 return this.count() >= 2 &&299 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Member &&300 (<TypeScript.BinaryExpression>this.asts[this.top - 1]).operand1 === this.asts[this.top - 0];301 }302 public isMemberOfMember(): boolean {303 return this.count() >= 2 &&304 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Member &&305 (<TypeScript.BinaryExpression>this.asts[this.top - 1]).operand2 === this.asts[this.top - 0];306 }307 public isItemOfList(): boolean {308 return this.count() >= 2 &&309 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List;310 //(<Tools.ASTList>this.asts[this.top - 1]).operand2 === this.asts[this.top - 0];311 }312 public isThenOfIf(): boolean {313 return this.count() >= 2 &&314 this.asts[this.top - 1].nodeType === TypeScript.NodeType.If &&315 (<TypeScript.IfStatement>this.asts[this.top - 1]).thenBod == this.asts[this.top - 0];316 }317 public isElseOfIf(): boolean {318 return this.count() >= 2 &&319 this.asts[this.top - 1].nodeType === TypeScript.NodeType.If &&320 (<TypeScript.IfStatement>this.asts[this.top - 1]).elseBod == this.asts[this.top - 0];321 }322 public isBodyOfDefaultCase(): boolean {323 return this.isBodyOfCase();324 }325 public isSingleStatementList(): boolean {326 return this.count() >= 1 &&327 this.asts[this.top].nodeType === TypeScript.NodeType.List &&328 (<TypeScript.ASTList>this.asts[this.top]).members.length === 1;329 }330 public isArgumentListOfFunction(): boolean {331 return this.count() >= 2 &&332 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&333 this.asts[this.top - 1].nodeType === TypeScript.NodeType.FuncDecl &&334 (<TypeScript.FuncDecl>this.asts[this.top - 1]).arguments === this.asts[this.top - 0];335 }336 public isArgumentOfFunction(): boolean {337 return this.count() >= 3 &&338 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&339 this.asts[this.top - 2].nodeType === TypeScript.NodeType.FuncDecl &&340 (<TypeScript.FuncDecl>this.asts[this.top - 2]).arguments === this.asts[this.top - 1];341 }342 public isArgumentListOfCall(): boolean {343 return this.count() >= 2 &&344 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&345 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Call &&346 (<TypeScript.CallExpression>this.asts[this.top - 1]).arguments === this.asts[this.top - 0];347 }348 public isArgumentListOfNew(): boolean {349 return this.count() >= 2 &&350 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&351 this.asts[this.top - 1].nodeType === TypeScript.NodeType.New &&352 (<TypeScript.CallExpression>this.asts[this.top - 1]).arguments === this.asts[this.top - 0];353 }354 public isSynthesizedBlock(): boolean {355 return this.count() >= 1 &&356 this.asts[this.top - 0].nodeType === TypeScript.NodeType.Block &&357 (<TypeScript.Block>this.asts[this.top - 0]).isStatementBlock === false;358 }359 }360 export function isValidAstNode(ast: TypeScript.ASTSpan): boolean {361 if (ast === null)362 return false;363 if (ast.minChar === -1 || ast.limChar === -1)364 return false;365 return true;366 }367 export class AstPathContext {368 public path = new TypeScript.AstPath();369 }370 export enum GetAstPathOptions {371 Default = 0,372 EdgeInclusive = 1,373 //We need this options dealing with an AST coming from an incomplete AST. For example:374 // class foo { // r375 // If we ask for the AST at the position after the "r" character, we won't see we are 376 // inside a comment, because the "class" AST node has a limChar corresponding to the position of 377 // the "{" character, meaning we don't traverse the tree down to the stmt list of the class, meaning378 // we don't find the "precomment" attached to the errorneous empty stmt.379 //TODO: It would be nice to be able to get rid of this.380 DontPruneSearchBasedOnPosition = 1 << 1,381 }382 ///383 /// Return the stack of AST nodes containing "position"384 ///385 export function getAstPathToPosition(script: TypeScript.AST, pos: number, options = GetAstPathOptions.Default): TypeScript.AstPath {386 var lookInComments = (comments: TypeScript.Comment[]) => {387 if (comments && comments.length > 0) {388 for (var i = 0; i < comments.length; i++) {389 var minChar = comments[i].minChar;390 var limChar = comments[i].limChar;391 if (!comments[i].isBlockComment) {392 limChar++; // For single line comments, include 1 more character (for the newline)393 }394 if (pos >= minChar && pos < limChar) {395 ctx.path.push(comments[i]);396 }397 }398 }399 }400 var pre = function (cur: TypeScript.AST, parent: TypeScript.AST, walker: IAstWalker) {401 if (isValidAstNode(cur)) {402 // Add "cur" to the stack if it contains our position403 // For "identifier" nodes, we need a special case: A position equal to "limChar" is404 // valid, since the position corresponds to a caret position (in between characters)405 // For example:406 // bar407 // 0123408 // If "position == 3", the caret is at the "right" of the "r" character, which should be considered valid409 var inclusive =410 hasFlag(options, GetAstPathOptions.EdgeInclusive) ||411 cur.nodeType === TypeScript.NodeType.Name ||412 pos === script.limChar; // Special "EOF" case413 var minChar = cur.minChar;414 var limChar = cur.limChar + (inclusive ? 1 : 0)415 if (pos >= minChar && pos < limChar) {416 // TODO: Since AST is sometimes not correct wrt to position, only add "cur" if it's better417 // than top of the stack.418 var previous = ctx.path.ast();419 if (previous == null || (cur.minChar >= previous.minChar && cur.limChar <= previous.limChar)) {420 ctx.path.push(cur);421 }422 else {423 //logger.log("TODO: Ignoring node because minChar, limChar not better than previous node in stack");424 }425 }426 // The AST walker skips comments, but we might be in one, so check the pre/post comments for this node manually427 if (pos < limChar) {428 lookInComments(cur.preComments);429 }430 if (pos >= minChar) {431 lookInComments(cur.postComments);432 }433 if (!hasFlag(options, GetAstPathOptions.DontPruneSearchBasedOnPosition)) {434 // Don't go further down the tree if pos is outside of [minChar, limChar]435 walker.options.goChildren = (minChar <= pos && pos <= limChar);436 }437 }438 return cur;439 }440 var ctx = new AstPathContext();441 TypeScript.getAstWalkerFactory().walk(script, pre, null, null, ctx);442 return ctx.path;443 }444 //445 // Find a source text offset that is safe for lexing tokens at the given position.446 // This is used when "position" might be inside a comment or string, etc.447 //448 export function getTokenizationOffset(script: TypeScript.Script, position: number): number {449 var bestOffset = 0;450 var pre = (cur: TypeScript.AST, parent: TypeScript.AST, walker: TypeScript.IAstWalker): TypeScript.AST => {451 if (TypeScript.isValidAstNode(cur)) {452 // Did we find a closer offset?453 if (cur.minChar <= position) {454 bestOffset = max(bestOffset, cur.minChar);455 }456 // Stop the walk if this node is not related to "minChar"457 if (cur.minChar > position || cur.limChar < bestOffset) {458 walker.options.goChildren = false;459 }460 }461 return cur;462 }463 TypeScript.getAstWalkerFactory().walk(script, pre);464 return bestOffset;465 }466 ///467 /// Simple function to Walk an AST using a simple callback function.468 ///469 export function walkAST(ast: TypeScript.AST, callback: (path: AstPath, walker: TypeScript.IAstWalker) => void ): void {470 var pre = function (cur: TypeScript.AST, parent: TypeScript.AST, walker: TypeScript.IAstWalker) {471 var path: TypeScript.AstPath = walker.state;472 path.push(cur);473 callback(path, walker);474 return cur;475 }476 var post = function (cur: TypeScript.AST, parent: TypeScript.AST, walker: TypeScript.IAstWalker) {477 var path: TypeScript.AstPath = walker.state;478 path.pop();479 return cur;480 }481 var path = new AstPath();482 TypeScript.getAstWalkerFactory().walk(ast, pre, post, null, path);483 }484}485486487//// [parserRealSource14.js]488// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0. 489// See LICENSE.txt in the project root for complete license information.490///<reference path='typescript.ts' />491var TypeScript;492(function (TypeScript) {493 function lastOf(items) {494 return (items === null || items.length === 0) ? null : items[items.length - 1];495 }496 TypeScript.lastOf = lastOf;497 function max(a, b) {498 return a >= b ? a : b;499 }500 TypeScript.max = max;501 function min(a, b) {502 return a <= b ? a : b;503 }504 TypeScript.min = min;505 //506 // Helper class representing a path from a root ast node to a (grand)child ast node.507 // This is helpful as our tree don't have parents.508 //509 var AstPath = /** @class */ (function () {510 function AstPath() {511 this.asts = [];512 this.top = -1;513 }514 AstPath.reverseIndexOf = function (items, index) {515 return (items === null || items.length <= index) ? null : items[items.length - index - 1];516 };517 AstPath.prototype.clone = function () {518 var clone = new AstPath();519 clone.asts = this.asts.map(function (value) { return value; });520 clone.top = this.top;521 return clone;522 };523 AstPath.prototype.pop = function () {524 var head = this.ast();525 this.up();526 while (this.asts.length > this.count()) {527 this.asts.pop();528 }529 return head;530 };531 AstPath.prototype.push = function (ast) {532 while (this.asts.length > this.count()) {533 this.asts.pop();534 }535 this.top = this.asts.length;536 this.asts.push(ast);537 };538 AstPath.prototype.up = function () {539 if (this.top <= -1)540 throw new Error("Invalid call to 'up'");541 this.top--;542 };543 AstPath.prototype.down = function () {544 if (this.top == this.ast.length - 1)545 throw new Error("Invalid call to 'down'");546 this.top++;547 };548 AstPath.prototype.nodeType = function () {549 if (this.ast() == null)550 return TypeScript.NodeType.None;551 return this.ast().nodeType;552 };553 AstPath.prototype.ast = function () {554 return AstPath.reverseIndexOf(this.asts, this.asts.length - (this.top + 1));555 };556 AstPath.prototype.parent = function () {557 return AstPath.reverseIndexOf(this.asts, this.asts.length - this.top);558 };559 AstPath.prototype.count = function () {560 return this.top + 1;561 };562 AstPath.prototype.get = function (index) {563 return this.asts[index];564 };565 AstPath.prototype.isNameOfClass = function () {566 if (this.ast() === null || this.parent() === null)567 return false;568 return (this.ast().nodeType === TypeScript.NodeType.Name) &&569 (this.parent().nodeType === TypeScript.NodeType.ClassDeclaration) &&570 (this.parent().name === this.ast());571 };572 AstPath.prototype.isNameOfInterface = function () {573 if (this.ast() === null || this.parent() === null)574 return false;575 return (this.ast().nodeType === TypeScript.NodeType.Name) &&576 (this.parent().nodeType === TypeScript.NodeType.InterfaceDeclaration) &&577 (this.parent().name === this.ast());578 };579 AstPath.prototype.isNameOfArgument = function () {580 if (this.ast() === null || this.parent() === null)581 return false;582 return (this.ast().nodeType === TypeScript.NodeType.Name) &&583 (this.parent().nodeType === TypeScript.NodeType.ArgDecl) &&584 (this.parent().id === this.ast());585 };586 AstPath.prototype.isNameOfVariable = function () {587 if (this.ast() === null || this.parent() === null)588 return false;589 return (this.ast().nodeType === TypeScript.NodeType.Name) &&590 (this.parent().nodeType === TypeScript.NodeType.VarDecl) &&591 (this.parent().id === this.ast());592 };593 AstPath.prototype.isNameOfModule = function () {594 if (this.ast() === null || this.parent() === null)595 return false;596 return (this.ast().nodeType === TypeScript.NodeType.Name) &&597 (this.parent().nodeType === TypeScript.NodeType.ModuleDeclaration) &&598 (this.parent().name === this.ast());599 };600 AstPath.prototype.isNameOfFunction = function () {601 if (this.ast() === null || this.parent() === null)602 return false;603 return (this.ast().nodeType === TypeScript.NodeType.Name) &&604 (this.parent().nodeType === TypeScript.NodeType.FuncDecl) &&605 (this.parent().name === this.ast());606 };607 AstPath.prototype.isChildOfScript = function () {608 var ast = lastOf(this.asts);609 return this.count() >= 3 &&610 this.asts[this.top] === ast &&611 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&612 this.asts[this.top - 2].nodeType === TypeScript.NodeType.Script;613 };614 AstPath.prototype.isChildOfModule = function () {615 var ast = lastOf(this.asts);616 return this.count() >= 3 &&617 this.asts[this.top] === ast &&618 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&619 this.asts[this.top - 2].nodeType === TypeScript.NodeType.ModuleDeclaration;620 };621 AstPath.prototype.isChildOfClass = function () {622 var ast = lastOf(this.asts);623 return this.count() >= 3 &&624 this.asts[this.top] === ast &&625 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&626 this.asts[this.top - 2].nodeType === TypeScript.NodeType.ClassDeclaration;627 };628 AstPath.prototype.isArgumentOfClassConstructor = function () {629 var ast = lastOf(this.asts);630 return this.count() >= 5 &&631 this.asts[this.top] === ast &&632 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&633 this.asts[this.top - 2].nodeType === TypeScript.NodeType.FuncDecl &&634 this.asts[this.top - 3].nodeType === TypeScript.NodeType.List &&635 this.asts[this.top - 4].nodeType === TypeScript.NodeType.ClassDeclaration &&636 (this.asts[this.top - 2].isConstructor) &&637 (this.asts[this.top - 2].arguments === this.asts[this.top - 1]) &&638 (this.asts[this.top - 4].constructorDecl === this.asts[this.top - 2]);639 };640 AstPath.prototype.isChildOfInterface = function () {641 var ast = lastOf(this.asts);642 return this.count() >= 3 &&643 this.asts[this.top] === ast &&644 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&645 this.asts[this.top - 2].nodeType === TypeScript.NodeType.InterfaceDeclaration;646 };647 AstPath.prototype.isTopLevelImplicitModule = function () {648 return this.count() >= 1 &&649 this.asts[this.top].nodeType === TypeScript.NodeType.ModuleDeclaration &&650 TypeScript.hasFlag(this.asts[this.top].modFlags, TypeScript.ModuleFlags.IsWholeFile);651 };652 AstPath.prototype.isBodyOfTopLevelImplicitModule = function () {653 return this.count() >= 2 &&654 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&655 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ModuleDeclaration &&656 this.asts[this.top - 1].members == this.asts[this.top - 0] &&657 TypeScript.hasFlag(this.asts[this.top - 1].modFlags, TypeScript.ModuleFlags.IsWholeFile);658 };659 AstPath.prototype.isBodyOfScript = function () {660 return this.count() >= 2 &&661 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Script &&662 this.asts[this.top - 1].bod == this.asts[this.top - 0];663 };664 AstPath.prototype.isBodyOfSwitch = function () {665 return this.count() >= 2 &&666 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Switch &&667 this.asts[this.top - 1].caseList == this.asts[this.top - 0];668 };669 AstPath.prototype.isBodyOfModule = function () {670 return this.count() >= 2 &&671 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ModuleDeclaration &&672 this.asts[this.top - 1].members == this.asts[this.top - 0];673 };674 AstPath.prototype.isBodyOfClass = function () {675 return this.count() >= 2 &&676 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ClassDeclaration &&677 this.asts[this.top - 1].members == this.asts[this.top - 0];678 };679 AstPath.prototype.isBodyOfFunction = function () {680 return this.count() >= 2 &&681 this.asts[this.top - 1].nodeType === TypeScript.NodeType.FuncDecl &&682 this.asts[this.top - 1].bod == this.asts[this.top - 0];683 };684 AstPath.prototype.isBodyOfInterface = function () {685 return this.count() >= 2 &&686 this.asts[this.top - 1].nodeType === TypeScript.NodeType.InterfaceDeclaration &&687 this.asts[this.top - 1].members == this.asts[this.top - 0];688 };689 AstPath.prototype.isBodyOfBlock = function () {690 return this.count() >= 2 &&691 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Block &&692 this.asts[this.top - 1].statements == this.asts[this.top - 0];693 };694 AstPath.prototype.isBodyOfFor = function () {695 return this.count() >= 2 &&696 this.asts[this.top - 1].nodeType === TypeScript.NodeType.For &&697 this.asts[this.top - 1].body == this.asts[this.top - 0];698 };699 AstPath.prototype.isBodyOfCase = function () {700 return this.count() >= 2 &&701 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Case &&702 this.asts[this.top - 1].body == this.asts[this.top - 0];703 };704 AstPath.prototype.isBodyOfTry = function () {705 return this.count() >= 2 &&706 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Try &&707 this.asts[this.top - 1].body == this.asts[this.top - 0];708 };709 AstPath.prototype.isBodyOfCatch = function () {710 return this.count() >= 2 &&711 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Catch &&712 this.asts[this.top - 1].body == this.asts[this.top - 0];713 };714 AstPath.prototype.isBodyOfDoWhile = function () {715 return this.count() >= 2 &&716 this.asts[this.top - 1].nodeType === TypeScript.NodeType.DoWhile &&717 this.asts[this.top - 1].body == this.asts[this.top - 0];718 };719 AstPath.prototype.isBodyOfWhile = function () {720 return this.count() >= 2 &&721 this.asts[this.top - 1].nodeType === TypeScript.NodeType.While &&722 this.asts[this.top - 1].body == this.asts[this.top - 0];723 };724 AstPath.prototype.isBodyOfForIn = function () {725 return this.count() >= 2 &&726 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ForIn &&727 this.asts[this.top - 1].body == this.asts[this.top - 0];728 };729 AstPath.prototype.isBodyOfWith = function () {730 return this.count() >= 2 &&731 this.asts[this.top - 1].nodeType === TypeScript.NodeType.With &&732 this.asts[this.top - 1].body == this.asts[this.top - 0];733 };734 AstPath.prototype.isBodyOfFinally = function () {735 return this.count() >= 2 &&736 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Finally &&737 this.asts[this.top - 1].body == this.asts[this.top - 0];738 };739 AstPath.prototype.isCaseOfSwitch = function () {740 return this.count() >= 3 &&741 this.asts[this.top - 2].nodeType === TypeScript.NodeType.Switch &&742 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&743 this.asts[this.top - 2].caseList == this.asts[this.top - 1];744 };745 AstPath.prototype.isDefaultCaseOfSwitch = function () {746 return this.count() >= 3 &&747 this.asts[this.top - 2].nodeType === TypeScript.NodeType.Switch &&748 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&749 this.asts[this.top - 2].caseList == this.asts[this.top - 1] &&750 this.asts[this.top - 2].defaultCase == this.asts[this.top - 0];751 };752 AstPath.prototype.isListOfObjectLit = function () {753 return this.count() >= 2 &&754 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ObjectLit &&755 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&756 this.asts[this.top - 1].operand == this.asts[this.top - 0];757 };758 AstPath.prototype.isBodyOfObjectLit = function () {759 return this.isListOfObjectLit();760 };761 AstPath.prototype.isEmptyListOfObjectLit = function () {762 return this.count() >= 2 &&763 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ObjectLit &&764 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&765 this.asts[this.top - 1].operand == this.asts[this.top - 0] &&766 this.asts[this.top - 0].members.length == 0;767 };768 AstPath.prototype.isMemberOfObjectLit = function () {769 return this.count() >= 3 &&770 this.asts[this.top - 2].nodeType === TypeScript.NodeType.ObjectLit &&771 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&772 this.asts[this.top - 0].nodeType === TypeScript.NodeType.Member &&773 this.asts[this.top - 2].operand == this.asts[this.top - 1];774 };775 AstPath.prototype.isNameOfMemberOfObjectLit = function () {776 return this.count() >= 4 &&777 this.asts[this.top - 3].nodeType === TypeScript.NodeType.ObjectLit &&778 this.asts[this.top - 2].nodeType === TypeScript.NodeType.List &&779 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Member &&780 this.asts[this.top - 0].nodeType === TypeScript.NodeType.Name &&781 this.asts[this.top - 3].operand == this.asts[this.top - 2];782 };783 AstPath.prototype.isListOfArrayLit = function () {784 return this.count() >= 2 &&785 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ArrayLit &&786 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&787 this.asts[this.top - 1].operand == this.asts[this.top - 0];788 };789 AstPath.prototype.isTargetOfMember = function () {790 return this.count() >= 2 &&791 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Member &&792 this.asts[this.top - 1].operand1 === this.asts[this.top - 0];793 };794 AstPath.prototype.isMemberOfMember = function () {795 return this.count() >= 2 &&796 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Member &&797 this.asts[this.top - 1].operand2 === this.asts[this.top - 0];798 };799 AstPath.prototype.isItemOfList = function () {800 return this.count() >= 2 &&801 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List;802 //(<Tools.ASTList>this.asts[this.top - 1]).operand2 === this.asts[this.top - 0];803 };804 AstPath.prototype.isThenOfIf = function () {805 return this.count() >= 2 &&806 this.asts[this.top - 1].nodeType === TypeScript.NodeType.If &&807 this.asts[this.top - 1].thenBod == this.asts[this.top - 0];808 };809 AstPath.prototype.isElseOfIf = function () {810 return this.count() >= 2 &&811 this.asts[this.top - 1].nodeType === TypeScript.NodeType.If &&812 this.asts[this.top - 1].elseBod == this.asts[this.top - 0];813 };814 AstPath.prototype.isBodyOfDefaultCase = function () {815 return this.isBodyOfCase();816 };817 AstPath.prototype.isSingleStatementList = function () {818 return this.count() >= 1 &&819 this.asts[this.top].nodeType === TypeScript.NodeType.List &&820 this.asts[this.top].members.length === 1;821 };822 AstPath.prototype.isArgumentListOfFunction = function () {823 return this.count() >= 2 &&824 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&825 this.asts[this.top - 1].nodeType === TypeScript.NodeType.FuncDecl &&826 this.asts[this.top - 1].arguments === this.asts[this.top - 0];827 };828 AstPath.prototype.isArgumentOfFunction = function () {829 return this.count() >= 3 &&830 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&831 this.asts[this.top - 2].nodeType === TypeScript.NodeType.FuncDecl &&832 this.asts[this.top - 2].arguments === this.asts[this.top - 1];833 };834 AstPath.prototype.isArgumentListOfCall = function () {835 return this.count() >= 2 &&836 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&837 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Call &&838 this.asts[this.top - 1].arguments === this.asts[this.top - 0];839 };840 AstPath.prototype.isArgumentListOfNew = function () {841 return this.count() >= 2 &&842 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&843 this.asts[this.top - 1].nodeType === TypeScript.NodeType.New &&844 this.asts[this.top - 1].arguments === this.asts[this.top - 0];845 };846 AstPath.prototype.isSynthesizedBlock = function () {847 return this.count() >= 1 &&848 this.asts[this.top - 0].nodeType === TypeScript.NodeType.Block &&849 this.asts[this.top - 0].isStatementBlock === false;850 };851 return AstPath;852 }());853 TypeScript.AstPath = AstPath;854 function isValidAstNode(ast) {855 if (ast === null)856 return false;857 if (ast.minChar === -1 || ast.limChar === -1)858 return false;859 return true;860 }861 TypeScript.isValidAstNode = isValidAstNode;862 var AstPathContext = /** @class */ (function () {863 function AstPathContext() {864 this.path = new TypeScript.AstPath();865 }866 return AstPathContext;867 }());868 TypeScript.AstPathContext = AstPathContext;869 var GetAstPathOptions;870 (function (GetAstPathOptions) {871 GetAstPathOptions[GetAstPathOptions["Default"] = 0] = "Default";872 GetAstPathOptions[GetAstPathOptions["EdgeInclusive"] = 1] = "EdgeInclusive";873 //We need this options dealing with an AST coming from an incomplete AST. For example:874 // class foo { // r875 // If we ask for the AST at the position after the "r" character, we won't see we are 876 // inside a comment, because the "class" AST node has a limChar corresponding to the position of 877 // the "{" character, meaning we don't traverse the tree down to the stmt list of the class, meaning878 // we don't find the "precomment" attached to the errorneous empty stmt.879 //TODO: It would be nice to be able to get rid of this.880 GetAstPathOptions[GetAstPathOptions["DontPruneSearchBasedOnPosition"] = 2] = "DontPruneSearchBasedOnPosition";881 })(GetAstPathOptions = TypeScript.GetAstPathOptions || (TypeScript.GetAstPathOptions = {}));882 ///883 /// Return the stack of AST nodes containing "position"884 ///885 function getAstPathToPosition(script, pos, options) {886 if (options === void 0) { options = GetAstPathOptions.Default; }887 var lookInComments = function (comments) {888 if (comments && comments.length > 0) {889 for (var i = 0; i < comments.length; i++) {890 var minChar = comments[i].minChar;891 var limChar = comments[i].limChar;892 if (!comments[i].isBlockComment) {893 limChar++; // For single line comments, include 1 more character (for the newline)894 }895 if (pos >= minChar && pos < limChar) {896 ctx.path.push(comments[i]);897 }898 }899 }900 };901 var pre = function (cur, parent, walker) {902 if (isValidAstNode(cur)) {903 // Add "cur" to the stack if it contains our position904 // For "identifier" nodes, we need a special case: A position equal to "limChar" is905 // valid, since the position corresponds to a caret position (in between characters)906 // For example:907 // bar908 // 0123909 // If "position == 3", the caret is at the "right" of the "r" character, which should be considered valid910 var inclusive = hasFlag(options, GetAstPathOptions.EdgeInclusive) ||911 cur.nodeType === TypeScript.NodeType.Name ||912 pos === script.limChar; // Special "EOF" case913 var minChar = cur.minChar;914 var limChar = cur.limChar + (inclusive ? 1 : 0);915 if (pos >= minChar && pos < limChar) {916 // TODO: Since AST is sometimes not correct wrt to position, only add "cur" if it's better917 // than top of the stack.918 var previous = ctx.path.ast();919 if (previous == null || (cur.minChar >= previous.minChar && cur.limChar <= previous.limChar)) {920 ctx.path.push(cur);921 }922 else {923 //logger.log("TODO: Ignoring node because minChar, limChar not better than previous node in stack");924 }925 }926 // The AST walker skips comments, but we might be in one, so check the pre/post comments for this node manually927 if (pos < limChar) {928 lookInComments(cur.preComments);929 }930 if (pos >= minChar) {931 lookInComments(cur.postComments);932 }933 if (!hasFlag(options, GetAstPathOptions.DontPruneSearchBasedOnPosition)) {934 // Don't go further down the tree if pos is outside of [minChar, limChar]935 walker.options.goChildren = (minChar <= pos && pos <= limChar);936 }937 }938 return cur;939 };940 var ctx = new AstPathContext();941 TypeScript.getAstWalkerFactory().walk(script, pre, null, null, ctx);942 return ctx.path;943 }944 TypeScript.getAstPathToPosition = getAstPathToPosition;945 //946 // Find a source text offset that is safe for lexing tokens at the given position.947 // This is used when "position" might be inside a comment or string, etc.948 //949 function getTokenizationOffset(script, position) {950 var bestOffset = 0;951 var pre = function (cur, parent, walker) {952 if (TypeScript.isValidAstNode(cur)) {953 // Did we find a closer offset?954 if (cur.minChar <= position) {955 bestOffset = max(bestOffset, cur.minChar);956 }957 // Stop the walk if this node is not related to "minChar"958 if (cur.minChar > position || cur.limChar < bestOffset) {959 walker.options.goChildren = false;960 }961 }962 return cur;963 };964 TypeScript.getAstWalkerFactory().walk(script, pre);965 return bestOffset;966 }967 TypeScript.getTokenizationOffset = getTokenizationOffset;968 ///969 /// Simple function to Walk an AST using a simple callback function.970 ///971 function walkAST(ast, callback) {972 var pre = function (cur, parent, walker) {973 var path = walker.state;974 path.push(cur);975 callback(path, walker);976 return cur;977 };978 var post = function (cur, parent, walker) {979 var path = walker.state;980 path.pop();981 return cur;982 };983 var path = new AstPath();984 TypeScript.getAstWalkerFactory().walk(ast, pre, post, null, path);985 }986 TypeScript.walkAST = walkAST;
...
parserRealSource14.ts
Source:parserRealSource14.ts
1// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0. 2// See LICENSE.txt in the project root for complete license information.34///<reference path='typescript.ts' />56module TypeScript {7 export function lastOf(items: any[]): any {8 return (items === null || items.length === 0) ? null : items[items.length - 1];9 }1011 export function max(a: number, b: number): number {12 return a >= b ? a : b;13 }1415 export function min(a: number, b: number): number {16 return a <= b ? a : b;17 }1819 //20 // Helper class representing a path from a root ast node to a (grand)child ast node.21 // This is helpful as our tree don't have parents.22 //23 export class AstPath {24 public asts: TypeScript.AST[] = [];25 public top: number = -1;2627 static reverseIndexOf(items: any[], index: number): any {28 return (items === null || items.length <= index) ? null : items[items.length - index - 1];29 }3031 public clone(): AstPath {32 var clone = new AstPath();33 clone.asts = this.asts.map((value) => { return value; });34 clone.top = this.top;35 return clone;36 }3738 public pop(): TypeScript.AST {39 var head = this.ast();40 this.up();4142 while (this.asts.length > this.count()) {43 this.asts.pop();44 }45 return head;46 }4748 public push(ast: TypeScript.AST) {49 while (this.asts.length > this.count()) {50 this.asts.pop();51 }52 this.top = this.asts.length;53 this.asts.push(ast);54 }5556 public up() {57 if (this.top <= -1)58 throw new Error("Invalid call to 'up'");59 this.top--;60 }6162 public down() {63 if (this.top == this.ast.length - 1)64 throw new Error("Invalid call to 'down'");65 this.top++;66 }6768 public nodeType(): TypeScript.NodeType {69 if (this.ast() == null)70 return TypeScript.NodeType.None;71 return this.ast().nodeType;72 }7374 public ast() {75 return <TypeScript.AST>AstPath.reverseIndexOf(this.asts, this.asts.length - (this.top + 1));76 }7778 public parent() {79 return <TypeScript.AST>AstPath.reverseIndexOf(this.asts, this.asts.length - this.top);80 }8182 public count() {83 return this.top + 1;84 }8586 public get(index: number): TypeScript.AST {87 return this.asts[index];88 }8990 public isNameOfClass(): boolean {91 if (this.ast() === null || this.parent() === null)92 return false;9394 return (this.ast().nodeType === TypeScript.NodeType.Name) &&95 (this.parent().nodeType === TypeScript.NodeType.ClassDeclaration) &&96 ((<TypeScript.InterfaceDeclaration>this.parent()).name === this.ast());97 }9899 public isNameOfInterface(): boolean {100 if (this.ast() === null || this.parent() === null)101 return false;102103 return (this.ast().nodeType === TypeScript.NodeType.Name) &&104 (this.parent().nodeType === TypeScript.NodeType.InterfaceDeclaration) &&105 ((<TypeScript.InterfaceDeclaration>this.parent()).name === this.ast());106 }107108 public isNameOfArgument(): boolean {109 if (this.ast() === null || this.parent() === null)110 return false;111112 return (this.ast().nodeType === TypeScript.NodeType.Name) &&113 (this.parent().nodeType === TypeScript.NodeType.ArgDecl) &&114 ((<TypeScript.ArgDecl>this.parent()).id === this.ast());115 }116117 public isNameOfVariable(): boolean {118 if (this.ast() === null || this.parent() === null)119 return false;120121 return (this.ast().nodeType === TypeScript.NodeType.Name) &&122 (this.parent().nodeType === TypeScript.NodeType.VarDecl) &&123 ((<TypeScript.VarDecl>this.parent()).id === this.ast());124 }125126 public isNameOfModule(): boolean {127 if (this.ast() === null || this.parent() === null)128 return false;129130 return (this.ast().nodeType === TypeScript.NodeType.Name) &&131 (this.parent().nodeType === TypeScript.NodeType.ModuleDeclaration) &&132 ((<TypeScript.ModuleDeclaration>this.parent()).name === this.ast());133 }134135 public isNameOfFunction(): boolean {136 if (this.ast() === null || this.parent() === null)137 return false;138139 return (this.ast().nodeType === TypeScript.NodeType.Name) &&140 (this.parent().nodeType === TypeScript.NodeType.FuncDecl) &&141 ((<TypeScript.FuncDecl>this.parent()).name === this.ast());142 }143144 public isChildOfScript(): boolean {145 var ast = lastOf(this.asts);146 return this.count() >= 3 &&147 this.asts[this.top] === ast &&148 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&149 this.asts[this.top - 2].nodeType === TypeScript.NodeType.Script;150 }151152 public isChildOfModule(): boolean {153 var ast = lastOf(this.asts);154 return this.count() >= 3 &&155 this.asts[this.top] === ast &&156 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&157 this.asts[this.top - 2].nodeType === TypeScript.NodeType.ModuleDeclaration;158 }159160 public isChildOfClass(): boolean {161 var ast = lastOf(this.asts);162 return this.count() >= 3 &&163 this.asts[this.top] === ast &&164 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&165 this.asts[this.top - 2].nodeType === TypeScript.NodeType.ClassDeclaration;166 }167168 public isArgumentOfClassConstructor(): boolean {169 var ast = lastOf(this.asts);170 return this.count() >= 5 &&171 this.asts[this.top] === ast &&172 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&173 this.asts[this.top - 2].nodeType === TypeScript.NodeType.FuncDecl &&174 this.asts[this.top - 3].nodeType === TypeScript.NodeType.List &&175 this.asts[this.top - 4].nodeType === TypeScript.NodeType.ClassDeclaration &&176 ((<TypeScript.FuncDecl>this.asts[this.top - 2]).isConstructor) &&177 ((<TypeScript.FuncDecl>this.asts[this.top - 2]).arguments === this.asts[this.top - 1]) &&178 ((<TypeScript.ClassDeclaration>this.asts[this.top - 4]).constructorDecl === this.asts[this.top - 2]);179 }180181 public isChildOfInterface(): boolean {182 var ast = lastOf(this.asts);183 return this.count() >= 3 &&184 this.asts[this.top] === ast &&185 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&186 this.asts[this.top - 2].nodeType === TypeScript.NodeType.InterfaceDeclaration;187 }188189 public isTopLevelImplicitModule() {190 return this.count() >= 1 &&191 this.asts[this.top].nodeType === TypeScript.NodeType.ModuleDeclaration &&192 TypeScript.hasFlag((<TypeScript.ModuleDeclaration>this.asts[this.top]).modFlags, TypeScript.ModuleFlags.IsWholeFile);193 }194195 public isBodyOfTopLevelImplicitModule() {196 return this.count() >= 2 &&197 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&198 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ModuleDeclaration &&199 (<TypeScript.ModuleDeclaration>this.asts[this.top - 1]).members == this.asts[this.top - 0] &&200 TypeScript.hasFlag((<TypeScript.ModuleDeclaration>this.asts[this.top - 1]).modFlags, TypeScript.ModuleFlags.IsWholeFile);201 }202203 public isBodyOfScript(): boolean {204 return this.count() >= 2 &&205 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Script &&206 (<TypeScript.Script>this.asts[this.top - 1]).bod == this.asts[this.top - 0];207 }208209 public isBodyOfSwitch(): boolean {210 return this.count() >= 2 &&211 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Switch &&212 (<TypeScript.SwitchStatement>this.asts[this.top - 1]).caseList == this.asts[this.top - 0];213 }214215 public isBodyOfModule(): boolean {216 return this.count() >= 2 &&217 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ModuleDeclaration &&218 (<TypeScript.ModuleDeclaration>this.asts[this.top - 1]).members == this.asts[this.top - 0];219 }220221 public isBodyOfClass(): boolean {222 return this.count() >= 2 &&223 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ClassDeclaration &&224 (<TypeScript.ClassDeclaration>this.asts[this.top - 1]).members == this.asts[this.top - 0];225 }226227 public isBodyOfFunction(): boolean {228 return this.count() >= 2 &&229 this.asts[this.top - 1].nodeType === TypeScript.NodeType.FuncDecl &&230 (<TypeScript.FuncDecl>this.asts[this.top - 1]).bod == this.asts[this.top - 0];231 }232233 public isBodyOfInterface(): boolean {234 return this.count() >= 2 &&235 this.asts[this.top - 1].nodeType === TypeScript.NodeType.InterfaceDeclaration &&236 (<TypeScript.InterfaceDeclaration>this.asts[this.top - 1]).members == this.asts[this.top - 0];237 }238239 public isBodyOfBlock(): boolean {240 return this.count() >= 2 &&241 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Block &&242 (<TypeScript.Block>this.asts[this.top - 1]).statements == this.asts[this.top - 0];243 }244245 public isBodyOfFor(): boolean {246 return this.count() >= 2 &&247 this.asts[this.top - 1].nodeType === TypeScript.NodeType.For &&248 (<TypeScript.ForStatement>this.asts[this.top - 1]).body == this.asts[this.top - 0];249 }250251 public isBodyOfCase(): boolean {252 return this.count() >= 2 &&253 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Case &&254 (<TypeScript.CaseStatement>this.asts[this.top - 1]).body == this.asts[this.top - 0];255 }256257 public isBodyOfTry(): boolean {258 return this.count() >= 2 &&259 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Try &&260 (<TypeScript.Try>this.asts[this.top - 1]).body == this.asts[this.top - 0];261 }262263 public isBodyOfCatch(): boolean {264 return this.count() >= 2 &&265 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Catch &&266 (<TypeScript.Catch>this.asts[this.top - 1]).body == this.asts[this.top - 0];267 }268269 public isBodyOfDoWhile(): boolean {270 return this.count() >= 2 &&271 this.asts[this.top - 1].nodeType === TypeScript.NodeType.DoWhile &&272 (<TypeScript.DoWhileStatement>this.asts[this.top - 1]).body == this.asts[this.top - 0];273 }274275 public isBodyOfWhile(): boolean {276 return this.count() >= 2 &&277 this.asts[this.top - 1].nodeType === TypeScript.NodeType.While &&278 (<TypeScript.WhileStatement>this.asts[this.top - 1]).body == this.asts[this.top - 0];279 }280281 public isBodyOfForIn(): boolean {282 return this.count() >= 2 &&283 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ForIn &&284 (<TypeScript.ForInStatement>this.asts[this.top - 1]).body == this.asts[this.top - 0];285 }286287 public isBodyOfWith(): boolean {288 return this.count() >= 2 &&289 this.asts[this.top - 1].nodeType === TypeScript.NodeType.With &&290 (<TypeScript.WithStatement>this.asts[this.top - 1]).body == this.asts[this.top - 0];291 }292293 public isBodyOfFinally(): boolean {294 return this.count() >= 2 &&295 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Finally &&296 (<TypeScript.Finally>this.asts[this.top - 1]).body == this.asts[this.top - 0];297 }298299 public isCaseOfSwitch(): boolean {300 return this.count() >= 3 &&301 this.asts[this.top - 2].nodeType === TypeScript.NodeType.Switch &&302 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&303 (<TypeScript.SwitchStatement>this.asts[this.top - 2]).caseList == this.asts[this.top - 1];304 }305306 public isDefaultCaseOfSwitch(): boolean {307 return this.count() >= 3 &&308 this.asts[this.top - 2].nodeType === TypeScript.NodeType.Switch &&309 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&310 (<TypeScript.SwitchStatement>this.asts[this.top - 2]).caseList == this.asts[this.top - 1] &&311 (<TypeScript.SwitchStatement>this.asts[this.top - 2]).defaultCase == this.asts[this.top - 0];312 }313314 public isListOfObjectLit(): boolean {315 return this.count() >= 2 &&316 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ObjectLit &&317 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&318 (<TypeScript.UnaryExpression>this.asts[this.top - 1]).operand == this.asts[this.top - 0];319 }320321 public isBodyOfObjectLit(): boolean {322 return this.isListOfObjectLit();323 }324325 public isEmptyListOfObjectLit(): boolean {326 return this.count() >= 2 &&327 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ObjectLit &&328 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&329 (<TypeScript.UnaryExpression>this.asts[this.top - 1]).operand == this.asts[this.top - 0] &&330 (<TypeScript.ASTList>this.asts[this.top - 0]).members.length == 0;331 }332333 public isMemberOfObjectLit(): boolean {334 return this.count() >= 3 &&335 this.asts[this.top - 2].nodeType === TypeScript.NodeType.ObjectLit &&336 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&337 this.asts[this.top - 0].nodeType === TypeScript.NodeType.Member &&338 (<TypeScript.UnaryExpression>this.asts[this.top - 2]).operand == this.asts[this.top - 1];339 }340341 public isNameOfMemberOfObjectLit(): boolean {342 return this.count() >= 4 &&343 this.asts[this.top - 3].nodeType === TypeScript.NodeType.ObjectLit &&344 this.asts[this.top - 2].nodeType === TypeScript.NodeType.List &&345 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Member &&346 this.asts[this.top - 0].nodeType === TypeScript.NodeType.Name &&347 (<TypeScript.UnaryExpression>this.asts[this.top - 3]).operand == this.asts[this.top - 2];348 }349350 public isListOfArrayLit(): boolean {351 return this.count() >= 2 &&352 this.asts[this.top - 1].nodeType === TypeScript.NodeType.ArrayLit &&353 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&354 (<TypeScript.UnaryExpression>this.asts[this.top - 1]).operand == this.asts[this.top - 0];355 }356357 public isTargetOfMember(): boolean {358 return this.count() >= 2 &&359 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Member &&360 (<TypeScript.BinaryExpression>this.asts[this.top - 1]).operand1 === this.asts[this.top - 0];361 }362363 public isMemberOfMember(): boolean {364 return this.count() >= 2 &&365 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Member &&366 (<TypeScript.BinaryExpression>this.asts[this.top - 1]).operand2 === this.asts[this.top - 0];367 }368369 public isItemOfList(): boolean {370 return this.count() >= 2 &&371 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List;372 //(<Tools.ASTList>this.asts[this.top - 1]).operand2 === this.asts[this.top - 0];373 }374375 public isThenOfIf(): boolean {376 return this.count() >= 2 &&377 this.asts[this.top - 1].nodeType === TypeScript.NodeType.If &&378 (<TypeScript.IfStatement>this.asts[this.top - 1]).thenBod == this.asts[this.top - 0];379 }380381 public isElseOfIf(): boolean {382 return this.count() >= 2 &&383 this.asts[this.top - 1].nodeType === TypeScript.NodeType.If &&384 (<TypeScript.IfStatement>this.asts[this.top - 1]).elseBod == this.asts[this.top - 0];385 }386387 public isBodyOfDefaultCase(): boolean {388 return this.isBodyOfCase();389 }390391 public isSingleStatementList(): boolean {392 return this.count() >= 1 &&393 this.asts[this.top].nodeType === TypeScript.NodeType.List &&394 (<TypeScript.ASTList>this.asts[this.top]).members.length === 1;395 }396397 public isArgumentListOfFunction(): boolean {398 return this.count() >= 2 &&399 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&400 this.asts[this.top - 1].nodeType === TypeScript.NodeType.FuncDecl &&401 (<TypeScript.FuncDecl>this.asts[this.top - 1]).arguments === this.asts[this.top - 0];402 }403404 public isArgumentOfFunction(): boolean {405 return this.count() >= 3 &&406 this.asts[this.top - 1].nodeType === TypeScript.NodeType.List &&407 this.asts[this.top - 2].nodeType === TypeScript.NodeType.FuncDecl &&408 (<TypeScript.FuncDecl>this.asts[this.top - 2]).arguments === this.asts[this.top - 1];409 }410411 public isArgumentListOfCall(): boolean {412 return this.count() >= 2 &&413 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&414 this.asts[this.top - 1].nodeType === TypeScript.NodeType.Call &&415 (<TypeScript.CallExpression>this.asts[this.top - 1]).arguments === this.asts[this.top - 0];416 }417418 public isArgumentListOfNew(): boolean {419 return this.count() >= 2 &&420 this.asts[this.top - 0].nodeType === TypeScript.NodeType.List &&421 this.asts[this.top - 1].nodeType === TypeScript.NodeType.New &&422 (<TypeScript.CallExpression>this.asts[this.top - 1]).arguments === this.asts[this.top - 0];423 }424425 public isSynthesizedBlock(): boolean {426 return this.count() >= 1 &&427 this.asts[this.top - 0].nodeType === TypeScript.NodeType.Block &&428 (<TypeScript.Block>this.asts[this.top - 0]).isStatementBlock === false;429 }430 }431432 export function isValidAstNode(ast: TypeScript.ASTSpan): boolean {433 if (ast === null)434 return false;435436 if (ast.minChar === -1 || ast.limChar === -1)437 return false;438439 return true;440 }441442 export class AstPathContext {443 public path = new TypeScript.AstPath();444 }445446 export enum GetAstPathOptions {447 Default = 0,448 EdgeInclusive = 1,449 //We need this options dealing with an AST coming from an incomplete AST. For example:450 // class foo { // r451 // If we ask for the AST at the position after the "r" character, we won't see we are 452 // inside a comment, because the "class" AST node has a limChar corresponding to the position of 453 // the "{" character, meaning we don't traverse the tree down to the stmt list of the class, meaning454 // we don't find the "precomment" attached to the errorneous empty stmt.455 //TODO: It would be nice to be able to get rid of this.456 DontPruneSearchBasedOnPosition = 1 << 1,457 }458459 ///460 /// Return the stack of AST nodes containing "position"461 ///462 export function getAstPathToPosition(script: TypeScript.AST, pos: number, options = GetAstPathOptions.Default): TypeScript.AstPath {463 var lookInComments = (comments: TypeScript.Comment[]) => {464 if (comments && comments.length > 0) {465 for (var i = 0; i < comments.length; i++) {466 var minChar = comments[i].minChar;467 var limChar = comments[i].limChar;468 if (!comments[i].isBlockComment) {469 limChar++; // For single line comments, include 1 more character (for the newline)470 }471 if (pos >= minChar && pos < limChar) {472 ctx.path.push(comments[i]);473 }474 }475 }476 }477478 var pre = function (cur: TypeScript.AST, parent: TypeScript.AST, walker: IAstWalker) {479 if (isValidAstNode(cur)) {480481 // Add "cur" to the stack if it contains our position482 // For "identifier" nodes, we need a special case: A position equal to "limChar" is483 // valid, since the position corresponds to a caret position (in between characters)484 // For example:485 // bar486 // 0123487 // If "position == 3", the caret is at the "right" of the "r" character, which should be considered valid488 var inclusive =489 hasFlag(options, GetAstPathOptions.EdgeInclusive) ||490 cur.nodeType === TypeScript.NodeType.Name ||491 pos === script.limChar; // Special "EOF" case492493 var minChar = cur.minChar;494 var limChar = cur.limChar + (inclusive ? 1 : 0)495 if (pos >= minChar && pos < limChar) {496497 // TODO: Since AST is sometimes not correct wrt to position, only add "cur" if it's better498 // than top of the stack.499 var previous = ctx.path.ast();500 if (previous == null || (cur.minChar >= previous.minChar && cur.limChar <= previous.limChar)) {501 ctx.path.push(cur);502 }503 else {504 //logger.log("TODO: Ignoring node because minChar, limChar not better than previous node in stack");505 }506 }507508 // The AST walker skips comments, but we might be in one, so check the pre/post comments for this node manually509 if (pos < limChar) {510 lookInComments(cur.preComments);511 }512 if (pos >= minChar) {513 lookInComments(cur.postComments);514 }515516 if (!hasFlag(options, GetAstPathOptions.DontPruneSearchBasedOnPosition)) {517 // Don't go further down the tree if pos is outside of [minChar, limChar]518 walker.options.goChildren = (minChar <= pos && pos <= limChar);519 }520 }521 return cur;522 }523524 var ctx = new AstPathContext();525 TypeScript.getAstWalkerFactory().walk(script, pre, null, null, ctx);526 return ctx.path;527 }528529 //530 // Find a source text offset that is safe for lexing tokens at the given position.531 // This is used when "position" might be inside a comment or string, etc.532 //533 export function getTokenizationOffset(script: TypeScript.Script, position: number): number {534 var bestOffset = 0;535 var pre = (cur: TypeScript.AST, parent: TypeScript.AST, walker: TypeScript.IAstWalker): TypeScript.AST => {536 if (TypeScript.isValidAstNode(cur)) {537 // Did we find a closer offset?538 if (cur.minChar <= position) {539 bestOffset = max(bestOffset, cur.minChar);540 }541542 // Stop the walk if this node is not related to "minChar"543 if (cur.minChar > position || cur.limChar < bestOffset) {544 walker.options.goChildren = false;545 }546 }547548 return cur;549 }550551 TypeScript.getAstWalkerFactory().walk(script, pre);552 return bestOffset;553 }554555 ///556 /// Simple function to Walk an AST using a simple callback function.557 ///558 export function walkAST(ast: TypeScript.AST, callback: (path: AstPath, walker: TypeScript.IAstWalker) => void ): void {559 var pre = function (cur: TypeScript.AST, parent: TypeScript.AST, walker: TypeScript.IAstWalker) {560 var path: TypeScript.AstPath = walker.state;561 path.push(cur);562 callback(path, walker);563 return cur;564 }565 var post = function (cur: TypeScript.AST, parent: TypeScript.AST, walker: TypeScript.IAstWalker) {566 var path: TypeScript.AstPath = walker.state;567 path.pop();568 return cur;569 }570571 var path = new AstPath();572 TypeScript.getAstWalkerFactory().walk(ast, pre, post, null, path);573 }
...
Using AI Code Generation
1var asts = require('stryker-parent').asts;2var esprima = require('esprima');3var estraverse = require('estraverse');4var escodegen = require('escodegen');5var fs = require('fs');6var code = fs.readFileSync('test.js', 'utf8');7var ast = esprima.parse(code);8asts.mutate(ast, function (node) {9 if (node.type === 'Identifier') {10 node.name = 'foo';11 }12});13var mutatedCode = escodegen.generate(ast);14console.log(mutatedCode);15var ast = esprima.parse(mutatedCode);16asts.mutate(ast, function (node) {17 if (node.type === 'Identifier') {18 node.name = 'bar';19 }20});21var mutatedCode = escodegen.generate(ast);22console.log(mutatedCode);23var ast = esprima.parse(mutatedCode);24asts.mutate(ast, function (node) {25 if (node.type === 'Identifier') {26 node.name = 'baz';27 }28});29var mutatedCode = escodegen.generate(ast);30console.log(mutatedCode);31var ast = esprima.parse(mutatedCode);32asts.mutate(ast, function (node) {33 if (node.type === 'Identifier') {34 node.name = 'qux';35 }36});37var mutatedCode = escodegen.generate(ast);38console.log(mutatedCode);39var ast = esprima.parse(mutatedCode);40asts.mutate(ast, function (node) {41 if (node.type === 'Identifier') {42 node.name = 'quux';43 }44});45var mutatedCode = escodegen.generate(ast);46console.log(mutatedCode);47var ast = esprima.parse(mutatedCode);48asts.mutate(ast, function (node) {49 if (node.type === 'Identifier') {50 node.name = 'corge';51 }52});53var mutatedCode = escodegen.generate(ast);54console.log(mutatedCode);55var ast = esprima.parse(mutatedCode);56asts.mutate(ast, function (node) {57 if (node.type === 'Identifier') {58 node.name = 'grault';59 }60});61var mutatedCode = escodegen.generate(ast);62console.log(mutatedCode);63var ast = esprima.parse(mutatedCode);64asts.mutate(ast, function (node) {65 if (node.type === 'Identifier') {
Using AI Code Generation
1const asts = require('stryker-parent').asts;2const asts = require('stryker-parent').asts;3const asts = require('stryker-parent').asts;4const asts = require('stryker-parent').asts;5const asts = require('stryker-parent').asts;6const asts = require('stryker-parent').asts;7const asts = require('stryker-parent').asts;8const asts = require('stryker-parent').asts;9const asts = require('stryker-parent').asts;10const asts = require('stryker-parent').asts;11const asts = require('stryker-parent').asts;12const asts = require('stryker-parent').asts;13const asts = require('stryker-parent').asts;14const asts = require('stryker-parent').asts;15const asts = require('stryker-parent').asts;16const asts = require('stryker-parent').asts;17const asts = require('stryker-parent').asts;18const asts = require('stryker-parent').asts;19const asts = require('stryker-parent').asts;20const asts = require('stryker-parent').asts;
Using AI Code Generation
1const strykerParent = require('stryker-parent');2const asts = strykerParent.asts;3const esprima = require('esprima');4const ast = esprima.parse('var a = "foo"');5console.log(asts.mutate(ast, 'foo', 'bar'));6const strykerParent = require('stryker-parent');7const asts = strykerParent.asts;8const esprima = require('esprima');9const ast = esprima.parse('var a = "foo"');10console.log(asts.mutate(ast, 'foo', 'bar'));11const strykerParent = require('stryker-parent');12const asts = strykerParent.asts;13const esprima = require('esprima');14const ast = esprima.parse('var a = "foo"');15console.log(asts.mutate(ast, 'foo', 'bar'));16const strykerParent = require('stryker-parent');17const asts = strykerParent.asts;18const esprima = require('esprima');19const ast = esprima.parse('var a = "foo"');20console.log(asts.mutate(ast, 'foo', 'bar'));21const strykerParent = require('stryker-parent');22const asts = strykerParent.asts;23const esprima = require('esprima');24const ast = esprima.parse('var a = "foo"');25console.log(asts.mutate(ast, 'foo', 'bar'));26const strykerParent = require('stryker-parent');27const asts = strykerParent.asts;28const esprima = require('esprima');29const ast = esprima.parse('var a = "foo"');30console.log(asts.mutate(ast, 'foo', 'bar'));
Using AI Code Generation
1var asts = require('stryker-parent').asts;2var parse = asts.parse;3var traverse = asts.traverse;4var types = asts.types;5var _ = require('lodash');6var code = 'var x = 5;';7var ast = parse(code);8traverse(ast, {9 enter: function(node) {10 if (node.type === 'BinaryExpression') {11 console.log('Found binary expression!');12 }13 }14});15var transformedAst = types.builders.binaryExpression('+', types.builders.identifier('x'), types.builders.literal(1));16console.log(transformedAst);17var code = 'var x = 5;';18var ast = parse(code);19var transformedAst = types.builders.binaryExpression('+', types.builders.identifier('x'), types.builders.literal(1));20traverse(ast, {21 enter: function(node) {22 if (node.type === 'BinaryExpression') {23 console.log('Found binary expression!');24 node = transformedAst;25 }26 }27});28console.log(ast);29var code = 'var x = 5;';30var ast = parse(code);31var transformedAst = types.builders.binaryExpression('+', types.builders.identifier('x'), types.builders.literal(1));32traverse(ast, {33 enter: function(node) {34 if (node.type === 'BinaryExpression') {35 console.log('Found binary expression!');36 return transformedAst;37 }38 }39});40console.log(ast);41var code = 'var x = 5;';42var ast = parse(code);43var transformedAst = types.builders.binaryExpression('+', types.builders.identifier('x'), types.builders.literal(1));44traverse(ast, {45 enter: function(node) {46 if (node.type === 'BinaryExpression') {47 console.log('Found binary expression!');48 return transformedAst;49 }50 }51});52console.log(ast);53var code = 'var x = 5;';54var ast = parse(code);55var transformedAst = types.builders.binaryExpression('+', types.builders.identifier('x'), types.builders.literal(1));56traverse(ast, {57 enter: function(node) {58 if (node.type === 'BinaryExpression') {59 console.log('Found binary expression!');60 return transformedAst;61 }62 }63});64console.log(ast);65var code = 'var x = 5;';
Using AI Code Generation
1const { parse } = require('stryker-parent');2const { parse } = require('stryker-parent');3const ast = parse('const a = 1;');4console.log(ast);5const { parse } = require('stryker-parent');6const ast = parse('const a = 1;');7console.log(ast);8const { parse } = require('stryker-parent');9const ast = parse('const a = 1;');10console.log(ast);11const { parse } = require('stryker-parent');12const ast = parse('const a = 1;');13console.log(ast);14const { parse } = require('stryker-parent');15const ast = parse('const a = 1;');16console.log(ast);17const { parse } = require('stryker-parent');18const ast = parse('const a = 1;');19console.log(ast);20const { parse } = require('stryker-parent');21const ast = parse('const a = 1;');22console.log(ast);23const { parse } = require('stryker-parent');24const ast = parse('const a = 1;');25console.log(ast);26const { parse } = require('stryker-parent');27const ast = parse('const a = 1;');28console.log(ast);29const { parse } = require('stryker-parent');30const ast = parse('const a = 1;');31console.log(ast);32const { parse } = require('stryker-parent');33const ast = parse('const a = 1;');34console.log(ast);35const { parse } = require('stryker-parent');36const ast = parse('const a = 1;');37console.log(ast);
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!