55 */
66'use strict' ;
77
8+ var has = require ( 'has' ) ;
9+ var find = require ( 'array.prototype.find' ) ;
10+
811var pragmaUtil = require ( '../util/pragma' ) ;
912var versionUtil = require ( '../util/version' ) ;
1013
1114// ------------------------------------------------------------------------------
1215// Constants
1316// ------------------------------------------------------------------------------
1417
18+ var MODULES = {
19+ react : [ 'React' ] ,
20+ 'react-addons-perf' : [ 'ReactPerf' , 'Perf' ]
21+ } ;
22+
1523var DEPRECATED_MESSAGE = '{{oldMethod}} is deprecated since React {{version}}{{newMethod}}' ;
1624
1725// ------------------------------------------------------------------------------
@@ -34,73 +42,123 @@ module.exports = {
3442 var pragma = pragmaUtil . getFromContext ( context ) ;
3543
3644 function getDeprecated ( ) {
37- var deprecated = {
38- MemberExpression : { }
39- } ;
45+ var deprecated = { } ;
4046 // 0.12.0
41- deprecated . MemberExpression [ pragma + '.renderComponent' ] = [ '0.12.0' , pragma + '.render' ] ;
42- deprecated . MemberExpression [ pragma + '.renderComponentToString' ] = [ '0.12.0' , pragma + '.renderToString' ] ;
43- deprecated . MemberExpression [ pragma + '.renderComponentToStaticMarkup' ] = [
44- '0.12.0' ,
45- pragma + '.renderToStaticMarkup'
46- ] ;
47- deprecated . MemberExpression [ pragma + '.isValidComponent' ] = [ '0.12.0' , pragma + '.isValidElement' ] ;
48- deprecated . MemberExpression [ pragma + '.PropTypes.component' ] = [ '0.12.0' , pragma + '.PropTypes.element' ] ;
49- deprecated . MemberExpression [ pragma + '.PropTypes.renderable' ] = [ '0.12.0' , pragma + '.PropTypes.node' ] ;
50- deprecated . MemberExpression [ pragma + '.isValidClass' ] = [ '0.12.0' ] ;
51- deprecated . MemberExpression [ 'this.transferPropsTo' ] = [ '0.12.0' , 'spread operator ({...})' ] ;
47+ deprecated [ pragma + '.renderComponent' ] = [ '0.12.0' , pragma + '.render' ] ;
48+ deprecated [ pragma + '.renderComponentToString' ] = [ '0.12.0' , pragma + '.renderToString' ] ;
49+ deprecated [ pragma + '.renderComponentToStaticMarkup' ] = [ '0.12.0' , pragma + '.renderToStaticMarkup' ] ;
50+ deprecated [ pragma + '.isValidComponent' ] = [ '0.12.0' , pragma + '.isValidElement' ] ;
51+ deprecated [ pragma + '.PropTypes.component' ] = [ '0.12.0' , pragma + '.PropTypes.element' ] ;
52+ deprecated [ pragma + '.PropTypes.renderable' ] = [ '0.12.0' , pragma + '.PropTypes.node' ] ;
53+ deprecated [ pragma + '.isValidClass' ] = [ '0.12.0' ] ;
54+ deprecated [ 'this.transferPropsTo' ] = [ '0.12.0' , 'spread operator ({...})' ] ;
5255 // 0.13.0
53- deprecated . MemberExpression [ pragma + '.addons.classSet' ] = [ '0.13.0' , 'the npm module classnames' ] ;
54- deprecated . MemberExpression [ pragma + '.addons.cloneWithProps' ] = [ '0.13.0' , pragma + '.cloneElement' ] ;
56+ deprecated [ pragma + '.addons.classSet' ] = [ '0.13.0' , 'the npm module classnames' ] ;
57+ deprecated [ pragma + '.addons.cloneWithProps' ] = [ '0.13.0' , pragma + '.cloneElement' ] ;
5558 // 0.14.0
56- deprecated . MemberExpression [ pragma + '.render' ] = [ '0.14.0' , 'ReactDOM.render' ] ;
57- deprecated . MemberExpression [ pragma + '.unmountComponentAtNode' ] = [ '0.14.0' , 'ReactDOM.unmountComponentAtNode' ] ;
58- deprecated . MemberExpression [ pragma + '.findDOMNode' ] = [ '0.14.0' , 'ReactDOM.findDOMNode' ] ;
59- deprecated . MemberExpression [ pragma + '.renderToString' ] = [ '0.14.0' , 'ReactDOMServer.renderToString' ] ;
60- deprecated . MemberExpression [ pragma + '.renderToStaticMarkup' ] = [ '0.14.0' , 'ReactDOMServer.renderToStaticMarkup' ] ;
59+ deprecated [ pragma + '.render' ] = [ '0.14.0' , 'ReactDOM.render' ] ;
60+ deprecated [ pragma + '.unmountComponentAtNode' ] = [ '0.14.0' , 'ReactDOM.unmountComponentAtNode' ] ;
61+ deprecated [ pragma + '.findDOMNode' ] = [ '0.14.0' , 'ReactDOM.findDOMNode' ] ;
62+ deprecated [ pragma + '.renderToString' ] = [ '0.14.0' , 'ReactDOMServer.renderToString' ] ;
63+ deprecated [ pragma + '.renderToStaticMarkup' ] = [ '0.14.0' , 'ReactDOMServer.renderToStaticMarkup' ] ;
6164 // 15.0.0
62- deprecated . MemberExpression [ pragma + '.addons.LinkedStateMixin' ] = [ '15.0.0' ] ;
63- deprecated . MemberExpression [ 'ReactPerf.printDOM' ] = [ '15.0.0' , 'ReactPerf.printOperations' ] ;
64- deprecated . MemberExpression [ 'Perf.printDOM' ] = [ '15.0.0' , 'Perf.printOperations' ] ;
65- deprecated . MemberExpression [ 'ReactPerf.getMeasurementsSummaryMap' ] = [ '15.0.0' , 'ReactPerf.getWasted' ] ;
66- deprecated . MemberExpression [ 'Perf.getMeasurementsSummaryMap' ] = [ '15.0.0' , 'Perf.getWasted' ] ;
65+ deprecated [ pragma + '.addons.LinkedStateMixin' ] = [ '15.0.0' ] ;
66+ deprecated [ 'ReactPerf.printDOM' ] = [ '15.0.0' , 'ReactPerf.printOperations' ] ;
67+ deprecated [ 'Perf.printDOM' ] = [ '15.0.0' , 'Perf.printOperations' ] ;
68+ deprecated [ 'ReactPerf.getMeasurementsSummaryMap' ] = [ '15.0.0' , 'ReactPerf.getWasted' ] ;
69+ deprecated [ 'Perf.getMeasurementsSummaryMap' ] = [ '15.0.0' , 'Perf.getWasted' ] ;
6770 // 15.5.0
68- deprecated . MemberExpression [ pragma + '.createClass' ] = [ '15.5.0' , 'the npm module create-react-class' ] ;
69- deprecated . MemberExpression [ pragma + '.PropTypes' ] = [ '15.5.0' , 'the npm module prop-types' ] ;
71+ deprecated [ pragma + '.createClass' ] = [ '15.5.0' , 'the npm module create-react-class' ] ;
72+ deprecated [ pragma + '.PropTypes' ] = [ '15.5.0' , 'the npm module prop-types' ] ;
7073
7174 return deprecated ;
7275 }
7376
74- function isDeprecated ( type , method ) {
77+ function isDeprecated ( method ) {
7578 var deprecated = getDeprecated ( ) ;
7679
7780 return (
78- deprecated [ type ] &&
79- deprecated [ type ] [ method ] &&
80- versionUtil . test ( context , deprecated [ type ] [ method ] [ 0 ] )
81+ deprecated &&
82+ deprecated [ method ] &&
83+ versionUtil . test ( context , deprecated [ method ] [ 0 ] )
8184 ) ;
8285 }
8386
87+ function checkDeprecation ( node , method ) {
88+ if ( ! isDeprecated ( method ) ) {
89+ return ;
90+ }
91+ var deprecated = getDeprecated ( ) ;
92+ context . report ( {
93+ node : node ,
94+ message : DEPRECATED_MESSAGE ,
95+ data : {
96+ oldMethod : method ,
97+ version : deprecated [ method ] [ 0 ] ,
98+ newMethod : deprecated [ method ] [ 1 ] ? ', use ' + deprecated [ method ] [ 1 ] + ' instead' : ''
99+ }
100+ } ) ;
101+ }
102+
103+ function getReactModuleName ( node ) {
104+ var moduleName = false ;
105+ if ( ! node . init ) {
106+ return moduleName ;
107+ }
108+ for ( var module in MODULES ) {
109+ if ( ! has ( MODULES , module ) ) {
110+ continue ;
111+ }
112+ moduleName = find ( MODULES [ module ] , function ( name ) {
113+ return name === node . init . name ;
114+ } ) ;
115+ if ( moduleName ) {
116+ break ;
117+ }
118+ }
119+ return moduleName ;
120+ }
121+
84122 // --------------------------------------------------------------------------
85123 // Public
86124 // --------------------------------------------------------------------------
87125
88126 return {
89127
90128 MemberExpression : function ( node ) {
91- var method = sourceCode . getText ( node ) ;
92- if ( ! isDeprecated ( node . type , method ) ) {
129+ checkDeprecation ( node , sourceCode . getText ( node ) ) ;
130+ } ,
131+
132+ ImportDeclaration : function ( node ) {
133+ var isReactImport = typeof MODULES [ node . source . value ] !== 'undefined' ;
134+ if ( ! isReactImport ) {
93135 return ;
94136 }
95- var deprecated = getDeprecated ( ) ;
96- context . report ( {
97- node : node ,
98- message : DEPRECATED_MESSAGE ,
99- data : {
100- oldMethod : method ,
101- version : deprecated [ node . type ] [ method ] [ 0 ] ,
102- newMethod : deprecated [ node . type ] [ method ] [ 1 ] ? ', use ' + deprecated [ node . type ] [ method ] [ 1 ] + ' instead' : ''
137+ node . specifiers . forEach ( function ( specifier ) {
138+ if ( ! specifier . imported ) {
139+ return ;
103140 }
141+ checkDeprecation ( node , MODULES [ node . source . value ] [ 0 ] + '.' + specifier . imported . name ) ;
142+ } ) ;
143+ } ,
144+
145+ VariableDeclarator : function ( node ) {
146+ var reactModuleName = getReactModuleName ( node ) ;
147+ var isRequire = node . init && node . init . callee && node . init . callee . name === 'require' ;
148+ var isReactRequire =
149+ node . init && node . init . arguments &&
150+ node . init . arguments . length && typeof MODULES [ node . init . arguments [ 0 ] . value ] !== 'undefined'
151+ ;
152+ var isDestructuring = node . id && node . id . type === 'ObjectPattern' ;
153+
154+ if (
155+ ! ( isDestructuring && reactModuleName ) &&
156+ ! ( isDestructuring && isRequire && isReactRequire )
157+ ) {
158+ return ;
159+ }
160+ node . id . properties . forEach ( function ( property ) {
161+ checkDeprecation ( node , ( reactModuleName || pragma ) + '.' + property . key . name ) ;
104162 } ) ;
105163 } ,
106164
0 commit comments