initial commit taken from gitlab.lrz.de

This commit is contained in:
privatereese
2018-08-24 18:09:42 +02:00
parent ae54ed4c48
commit fc05486403
28494 changed files with 2159823 additions and 0 deletions

22
node_modules/eslint-plugin-react-native/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 Tom Hastjarjanto
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

121
node_modules/eslint-plugin-react-native/README.md generated vendored Normal file
View File

@@ -0,0 +1,121 @@
ESLint plugin for React Native
==============================
[![Greenkeeper badge](https://badges.greenkeeper.io/Intellicode/eslint-plugin-react-native.svg)](https://greenkeeper.io/)
[![Maintenance Status][status-image]][status-url] [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][deps-image]][deps-url] [![Coverage Status][coverage-image]][coverage-url] [![Code Climate][climate-image]][climate-url] [![BCH compliance][bettercode-image]][bettercode-url]
React Native specific linting rules for ESLint. This repository is structured like (and contains code from) the excellent [eslint-plugin-react](http://github.com/yannickcr/eslint-plugin-react).
# Installation
Install [ESLint](https://www.github.com/eslint/eslint) either locally or globally.
```sh
$ npm install eslint
```
To make most use of this plugin, its recommended to install [eslint-plugin-react](http://github.com/yannickcr/eslint-plugin-react) in addition to [ESLint](https://www.github.com/eslint/eslint). If you installed `ESLint` globally, you have to install eslint-plugin-react globally too. Otherwise, install it locally.
```sh
$ npm install eslint-plugin-react
```
Similarly, install eslint-plugin-react-native
```sh
$ npm install eslint-plugin-react-native
```
# Configuration
Add `plugins` section and specify ESLint-plugin-React (optional) and ESLint-plugin-react-native as a plugin.
```json
{
"plugins": [
"react",
"react-native"
]
}
```
If it is not already the case you must also configure `ESLint` to support JSX.
```json
{
"ecmaFeatures": {
"jsx": true
}
}
```
In order to whitelist all *browser-like* globals, add `react-native/react-native` to your config.
```json
{
"env": {
"react-native/react-native": true
}
}
```
Finally, enable all of the rules that you would like to use.
```json
{
"rules": {
"react-native/no-unused-styles": 2,
"react-native/split-platform-components": 2,
"react-native/no-inline-styles": 2,
"react-native/no-color-literals": 2,
}
}
```
# List of supported rules
* [no-unused-styles](docs/rules/no-unused-styles.md): Detect `StyleSheet` rules which are not used in your React components
* [split-platform-components](docs/rules/split-platform-components.md): Enforce using platform specific filenames when necessary
* [no-inline-styles](docs/rules/no-inline-styles.md): Detect JSX components with inline styles that contain literal values
* [no-color-literals](docs/rules/no-color-literals.md): Detect `StyleSheet` rules and inline styles containing color literals instead of variables
[npm-url]: https://npmjs.org/package/eslint-plugin-react-native
[npm-image]: http://img.shields.io/npm/v/eslint-plugin-react-native.svg?style=flat-square
[travis-url]: https://travis-ci.org/Intellicode/eslint-plugin-react-native
[travis-image]: http://img.shields.io/travis/Intellicode/eslint-plugin-react-native/master.svg?style=flat-square
[deps-url]: https://david-dm.org/Intellicode/eslint-plugin-react-native
[deps-image]: https://img.shields.io/david/dev/Intellicode/eslint-plugin-react-native.svg?style=flat-square
[coverage-url]: https://coveralls.io/r/Intellicode/eslint-plugin-react-native?branch=master
[coverage-image]: http://img.shields.io/coveralls/Intellicode/eslint-plugin-react-native/master.svg?style=flat-square
[climate-url]: https://codeclimate.com/github/Intellicode/eslint-plugin-react-native
[climate-image]: http://img.shields.io/codeclimate/github/Intellicode/eslint-plugin-react-native.svg?style=flat-square
[status-url]: https://github.com/Intellicode/eslint-plugin-react-native/pulse
[status-image]: http://img.shields.io/badge/status-maintained-brightgreen.svg?style=flat-square
[bettercode-image]: https://bettercodehub.com/edge/badge/Intellicode/eslint-plugin-react-native
[bettercode-url]: https://bettercodehub.com
# Shareable configurations
## All
This plugin also exports an `all` configuration that includes every available rule.
```js
{
"plugins": [
/* ... */
"react-native"
],
"extends": [/* ... */, "plugin:react-native/all"]
}
```
**Note**: These configurations will import `eslint-plugin-react-native` and enable JSX in [parser options](http://eslint.org/docs/user-guide/configuring#specifying-parser-options).

52
node_modules/eslint-plugin-react-native/index.js generated vendored Normal file
View File

@@ -0,0 +1,52 @@
/* eslint-disable global-require */
'use strict';
const allRules = {
'no-unused-styles': require('./lib/rules/no-unused-styles'),
'no-inline-styles': require('./lib/rules/no-inline-styles'),
'no-color-literals': require('./lib/rules/no-color-literals'),
'split-platform-components': require('./lib/rules/split-platform-components'),
};
function configureAsError(rules) {
const result = {};
for (const key in rules) {
if (!rules.hasOwnProperty(key)) {
continue;
}
result['react-native/' + key] = 2;
}
return result;
}
const allRulesConfig = configureAsError(allRules);
module.exports = {
deprecatedRules: {},
rules: allRules,
rulesConfig: {
'no-unused-styles': 0,
'no-inline-styles': 0,
'no-color-literals': 0,
'split-platform-components': 0,
},
environments: {
'react-native': {
globals: require('eslint-plugin-react-native-globals').environments.all.globals,
},
},
configs: {
all: {
plugins: [
'react-native',
],
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
rules: allRulesConfig,
},
},
};

View File

@@ -0,0 +1,58 @@
/**
* @fileoverview Detects color literals
* @author Aaron Greenwald
*/
'use strict';
const util = require('util');
const Components = require('../util/Components');
const styleSheet = require('../util/stylesheet');
const StyleSheets = styleSheet.StyleSheets;
const astHelpers = styleSheet.astHelpers;
module.exports = Components.detect((context) => {
const styleSheets = new StyleSheets();
function reportColorLiterals(colorLiterals) {
if (colorLiterals) {
colorLiterals.forEach((style) => {
if (style) {
const expression = util.inspect(style.expression);
context.report({
node: style.node,
message: 'Color literal: {{expression}}',
data: { expression },
});
}
});
}
}
return {
VariableDeclarator: (node) => {
if (astHelpers.isStyleSheetDeclaration(node)) {
const styles = astHelpers.getStyleDeclarations(node);
if (styles) {
styles.forEach((style) => {
const literals = astHelpers.collectColorLiterals(style.value, context);
styleSheets.addColorLiterals(literals);
});
}
}
},
JSXAttribute: (node) => {
if (astHelpers.isStyleAttribute(node)) {
const literals = astHelpers.collectColorLiterals(node.value, context);
styleSheets.addColorLiterals(literals);
}
},
'Program:exit': () => reportColorLiterals(styleSheets.getColorLiterals()),
};
});
module.exports.schema = [];

View File

@@ -0,0 +1,45 @@
/**
* @fileoverview Detects inline styles
* @author Aaron Greenwald
*/
'use strict';
const util = require('util');
const Components = require('../util/Components');
const styleSheet = require('../util/stylesheet');
const StyleSheets = styleSheet.StyleSheets;
const astHelpers = styleSheet.astHelpers;
module.exports = Components.detect((context) => {
const styleSheets = new StyleSheets();
function reportInlineStyles(inlineStyles) {
if (inlineStyles) {
inlineStyles.forEach((style) => {
if (style) {
const expression = util.inspect(style.expression);
context.report({
node: style.node,
message: 'Inline style: {{expression}}',
data: { expression },
});
}
});
}
}
return {
JSXAttribute: (node) => {
if (astHelpers.isStyleAttribute(node)) {
const styles = astHelpers.collectStyleObjectExpressions(node.value, context);
styleSheets.addObjectExpressions(styles);
}
},
'Program:exit': () => reportInlineStyles(styleSheets.getObjectExpressions()),
};
});
module.exports.schema = [];

View File

@@ -0,0 +1,65 @@
/**
* @fileoverview Detects unused styles
* @author Tom Hastjarjanto
*/
'use strict';
const Components = require('../util/Components');
const styleSheet = require('../util/stylesheet');
const StyleSheets = styleSheet.StyleSheets;
const astHelpers = styleSheet.astHelpers;
module.exports = Components.detect((context, components) => {
const styleSheets = new StyleSheets();
const styleReferences = new Set();
function reportUnusedStyles(unusedStyles) {
Object.keys(unusedStyles).forEach((key) => {
if ({}.hasOwnProperty.call(unusedStyles, key)) {
const styles = unusedStyles[key];
styles.forEach((node) => {
const message = [
'Unused style detected: ',
key,
'.',
node.key.name,
].join('');
context.report(node, message);
});
}
});
}
return {
MemberExpression: function (node) {
const styleRef = astHelpers.getPotentialStyleReferenceFromMemberExpression(node);
if (styleRef) {
styleReferences.add(styleRef);
}
},
VariableDeclarator: function (node) {
if (astHelpers.isStyleSheetDeclaration(node)) {
const styleSheetName = astHelpers.getStyleSheetName(node);
const styles = astHelpers.getStyleDeclarations(node);
styleSheets.add(styleSheetName, styles);
}
},
'Program:exit': function () {
const list = components.all();
if (Object.keys(list).length > 0) {
styleReferences.forEach((reference) => {
styleSheets.markAsUsed(reference);
});
reportUnusedStyles(styleSheets.getUnusedReferences());
}
},
};
});
module.exports.schema = [];

View File

@@ -0,0 +1,91 @@
/**
* @fileoverview Android and IOS components should be
* used in platform specific React Native components.
* @author Tom Hastjarjanto
*/
'use strict';
module.exports = function (context) {
let reactComponents = [];
const androidMessage = 'Android components should be placed in android files';
const iosMessage = 'IOS components should be placed in ios files';
const conflictMessage = 'IOS and Android components can\'t be mixed';
const iosPathRegex = context.options[0] && context.options[0].iosPathRegex
? new RegExp(context.options[0].iosPathRegex)
: /\.ios\.js$/;
const androidPathRegex = context.options[0] && context.options[0].androidPathRegex
? new RegExp(context.options[0].androidPathRegex)
: /\.android\.js$/;
function getName(node) {
if (node.type === 'Property') {
const key = node.key || node.argument;
return key.type === 'Identifier' ? key.name : key.value;
} else if (node.type === 'Identifier') {
return node.name;
}
}
function hasNodeWithName(nodes, name) {
return nodes.some((node) => {
const nodeName = getName(node);
return nodeName && nodeName.includes(name);
});
}
function reportErrors(components, filename) {
const containsAndroidAndIOS = (
hasNodeWithName(components, 'IOS') &&
hasNodeWithName(components, 'Android')
);
components.forEach((node) => {
const propName = getName(node);
if (propName.includes('IOS') && !filename.match(iosPathRegex)) {
context.report(node, containsAndroidAndIOS ? conflictMessage : iosMessage);
}
if (propName.includes('Android') && !filename.match(androidPathRegex)) {
context.report(node, containsAndroidAndIOS ? conflictMessage : androidMessage);
}
});
}
return {
VariableDeclarator: function (node) {
const destructuring = node.init && node.id && node.id.type === 'ObjectPattern';
const statelessDestructuring = destructuring && node.init.name === 'React';
if (destructuring && statelessDestructuring) {
reactComponents = reactComponents.concat(node.id.properties);
}
},
ImportDeclaration: function (node) {
if (node.source.value === 'react-native') {
node.specifiers.forEach((importSpecifier) => {
if (importSpecifier.type === 'ImportSpecifier') {
reactComponents = reactComponents.concat(importSpecifier.imported);
}
});
}
},
'Program:exit': function () {
const filename = context.getFilename();
reportErrors(reactComponents, filename);
},
};
};
module.exports.schema = [{
type: 'object',
properties: {
androidPathRegex: {
type: 'string',
},
iosPathRegex: {
type: 'string',
},
},
additionalProperties: false,
}];

View File

@@ -0,0 +1,410 @@
/**
* @fileoverview Utility class and functions for React components detection
* @author Yannick Croissant
*/
'use strict';
/**
* Components
* @class
*/
function Components() {
this.list = {};
this.getId = function (node) {
return node && node.range.join(':');
};
}
/**
* Add a node to the components list, or update it if it's already in the list
*
* @param {ASTNode} node The AST node being added.
* @param {Number} confidence Confidence in the component detection (0=banned, 1=maybe, 2=yes)
*/
Components.prototype.add = function (node, confidence) {
const id = this.getId(node);
if (this.list[id]) {
if (confidence === 0 || this.list[id].confidence === 0) {
this.list[id].confidence = 0;
} else {
this.list[id].confidence = Math.max(this.list[id].confidence, confidence);
}
return;
}
this.list[id] = {
node: node,
confidence: confidence,
};
};
/**
* Find a component in the list using its node
*
* @param {ASTNode} node The AST node being searched.
* @returns {Object} Component object, undefined if the component is not found
*/
Components.prototype.get = function (node) {
const id = this.getId(node);
return this.list[id];
};
/**
* Update a component in the list
*
* @param {ASTNode} node The AST node being updated.
* @param {Object} props Additional properties to add to the component.
*/
Components.prototype.set = function (node, props) {
let currentNode = node;
while (currentNode && !this.list[this.getId(currentNode)]) {
currentNode = node.parent;
}
if (!currentNode) {
return;
}
const id = this.getId(currentNode);
this.list[id] = Object.assign({}, this.list[id], props);
};
/**
* Return the components list
* Components for which we are not confident are not returned
*
* @returns {Object} Components list
*/
Components.prototype.all = function () {
const list = {};
Object.keys(this.list).forEach((i) => {
if ({}.hasOwnProperty.call(this.list, i) && this.list[i].confidence >= 2) {
list[i] = this.list[i];
}
});
return list;
};
/**
* Return the length of the components list
* Components for which we are not confident are not counted
*
* @returns {Number} Components list length
*/
Components.prototype.length = function () {
let length = 0;
Object.keys(this.list).forEach((i) => {
if ({}.hasOwnProperty.call(this.list, i) && this.list[i].confidence >= 2) {
length += 1;
}
});
return length;
};
function componentRule(rule, context) {
const sourceCode = context.getSourceCode();
const components = new Components();
// Utilities for component detection
const utils = {
/**
* Check if the node is a React ES5 component
*
* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if the node is a React ES5 component, false if not
*/
isES5Component: function (node) {
if (!node.parent) {
return false;
}
return /^(React\.)?createClass$/.test(sourceCode.getText(node.parent.callee));
},
/**
* Check if the node is a React ES6 component
*
* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if the node is a React ES6 component, false if not
*/
isES6Component: function (node) {
if (!node.superClass) {
return false;
}
return /^(React\.)?(Pure)?Component$/.test(sourceCode.getText(node.superClass));
},
/**
* Check if the node is returning JSX
*
* @param {ASTNode} node The AST node being checked (must be a ReturnStatement).
* @returns {Boolean} True if the node is returning JSX, false if not
*/
isReturningJSX: function (node) {
let property;
switch (node.type) {
case 'ReturnStatement':
property = 'argument';
break;
case 'ArrowFunctionExpression':
property = 'body';
break;
default:
return false;
}
const returnsJSX =
node[property] &&
node[property].type === 'JSXElement'
;
const returnsReactCreateElement =
node[property] &&
node[property].callee &&
node[property].callee.property &&
node[property].callee.property.name === 'createElement'
;
return Boolean(returnsJSX || returnsReactCreateElement);
},
/**
* Get the parent component node from the current scope
*
* @returns {ASTNode} component node, null if we are not in a component
*/
getParentComponent: function () {
return (
utils.getParentES6Component() ||
utils.getParentES5Component() ||
utils.getParentStatelessComponent()
);
},
/**
* Get the parent ES5 component node from the current scope
*
* @returns {ASTNode} component node, null if we are not in a component
*/
getParentES5Component: function () {
let scope = context.getScope();
while (scope) {
const node = scope.block && scope.block.parent && scope.block.parent.parent;
if (node && utils.isES5Component(node)) {
return node;
}
scope = scope.upper;
}
return null;
},
/**
* Get the parent ES6 component node from the current scope
*
* @returns {ASTNode} component node, null if we are not in a component
*/
getParentES6Component: function () {
let scope = context.getScope();
while (scope && scope.type !== 'class') {
scope = scope.upper;
}
const node = scope && scope.block;
if (!node || !utils.isES6Component(node)) {
return null;
}
return node;
},
/**
* Get the parent stateless component node from the current scope
*
* @returns {ASTNode} component node, null if we are not in a component
*/
getParentStatelessComponent: function () {
let scope = context.getScope();
while (scope) {
const node = scope.block;
// Ignore non functions
const isFunction = /Function/.test(node.type);
// Ignore classes methods
const isNotMethod = !node.parent || node.parent.type !== 'MethodDefinition';
// Ignore arguments (callback, etc.)
const isNotArgument = !node.parent || node.parent.type !== 'CallExpression';
if (isFunction && isNotMethod && isNotArgument) {
return node;
}
scope = scope.upper;
}
return null;
},
/**
* Get the related component from a node
*
* @param {ASTNode} node The AST node being checked (must be a MemberExpression).
* @returns {ASTNode} component node, null if we cannot find the component
*/
getRelatedComponent: function (node) {
let currentNode = node;
let i;
let j;
let k;
let l;
// Get the component path
const componentPath = [];
while (currentNode) {
if (currentNode.property && currentNode.property.type === 'Identifier') {
componentPath.push(currentNode.property.name);
}
if (currentNode.object && currentNode.object.type === 'Identifier') {
componentPath.push(currentNode.object.name);
}
currentNode = currentNode.object;
}
componentPath.reverse();
// Find the variable in the current scope
const variableName = componentPath.shift();
if (!variableName) {
return null;
}
let variableInScope;
const variables = context.getScope().variables;
for (i = 0, j = variables.length; i < j; i++) { // eslint-disable-line no-plusplus
if (variables[i].name === variableName) {
variableInScope = variables[i];
break;
}
}
if (!variableInScope) {
return null;
}
// Find the variable declaration
let defInScope;
const defs = variableInScope.defs;
for (i = 0, j = defs.length; i < j; i++) { // eslint-disable-line no-plusplus
if (
defs[i].type === 'ClassName' ||
defs[i].type === 'FunctionName' ||
defs[i].type === 'Variable'
) {
defInScope = defs[i];
break;
}
}
if (!defInScope) {
return null;
}
currentNode = defInScope.node.init || defInScope.node;
// Traverse the node properties to the component declaration
for (i = 0, j = componentPath.length; i < j; i++) { // eslint-disable-line no-plusplus
if (!currentNode.properties) {
continue; // eslint-disable-line no-continue
}
for (k = 0, l = currentNode.properties.length; k < l; k++) { // eslint-disable-line no-plusplus, max-len
if (currentNode.properties[k].key.name === componentPath[i]) {
currentNode = currentNode.properties[k];
break;
}
}
if (!currentNode) {
return null;
}
currentNode = currentNode.value;
}
// Return the component
return components.get(currentNode);
},
};
// Component detection instructions
const detectionInstructions = {
ClassDeclaration: function (node) {
if (!utils.isES6Component(node)) {
return;
}
components.add(node, 2);
},
ClassProperty: function () {
const node = utils.getParentComponent();
if (!node) {
return;
}
components.add(node, 2);
},
ObjectExpression: function (node) {
if (!utils.isES5Component(node)) {
return;
}
components.add(node, 2);
},
FunctionExpression: function () {
const node = utils.getParentComponent();
if (!node) {
return;
}
components.add(node, 1);
},
FunctionDeclaration: function () {
const node = utils.getParentComponent();
if (!node) {
return;
}
components.add(node, 1);
},
ArrowFunctionExpression: function () {
const node = utils.getParentComponent();
if (!node) {
return;
}
if (node.expression && utils.isReturningJSX(node)) {
components.add(node, 2);
} else {
components.add(node, 1);
}
},
ThisExpression: function () {
const node = utils.getParentComponent();
if (!node || !/Function/.test(node.type)) {
return;
}
// Ban functions with a ThisExpression
components.add(node, 0);
},
ReturnStatement: function (node) {
if (!utils.isReturningJSX(node)) {
return;
}
const parentNode = utils.getParentComponent();
if (!parentNode) {
return;
}
components.add(parentNode, 2);
},
};
// Update the provided rule instructions to add the component detection
const ruleInstructions = rule(context, components, utils);
const updatedRuleInstructions = Object.assign({}, ruleInstructions);
Object.keys(detectionInstructions).forEach((instruction) => {
updatedRuleInstructions[instruction] = (node) => {
detectionInstructions[instruction](node);
return ruleInstructions[instruction] ? ruleInstructions[instruction](node) : undefined;
};
});
// Return the updated rule instructions
return updatedRuleInstructions;
}
Components.detect = function (rule) {
return componentRule.bind(this, rule);
};
module.exports = Components;

View File

@@ -0,0 +1,408 @@
'use strict';
/**
* StyleSheets represents the StyleSheets found in the source code.
* @constructor
*/
function StyleSheets() {
this.styleSheets = {};
}
/**
* Add adds a StyleSheet to our StyleSheets collections.
*
* @param {string} styleSheetName - The name of the StyleSheet.
* @param {object} properties - The collection of rules in the styleSheet.
*/
StyleSheets.prototype.add = function (styleSheetName, properties) {
this.styleSheets[styleSheetName] = properties;
};
/**
* MarkAsUsed marks a rule as used in our source code by removing it from the
* specified StyleSheet rules.
*
* @param {string} fullyQualifiedName - The fully qualified name of the rule.
* for example 'styles.text'
*/
StyleSheets.prototype.markAsUsed = function (fullyQualifiedName) {
const nameSplit = fullyQualifiedName.split('.');
const styleSheetName = nameSplit[0];
const styleSheetProperty = nameSplit[1];
if (this.styleSheets[styleSheetName]) {
this.styleSheets[styleSheetName] = this
.styleSheets[styleSheetName]
.filter(property => property.key.name !== styleSheetProperty);
}
};
/**
* GetUnusedReferences returns all collected StyleSheets and their
* unmarked rules.
*/
StyleSheets.prototype.getUnusedReferences = function () {
return this.styleSheets;
};
/**
* AddColorLiterals adds an array of expressions that contain color literals
* to the ColorLiterals collection
* @param {array} expressions - an array of expressions containing color literals
*/
StyleSheets.prototype.addColorLiterals = function (expressions) {
if (!this.colorLiterals) {
this.colorLiterals = [];
}
this.colorLiterals = this.colorLiterals.concat(expressions);
};
/**
* GetColorLiterals returns an array of collected color literals expressions
* @returns {Array}
*/
StyleSheets.prototype.getColorLiterals = function () {
return this.colorLiterals;
};
/**
* AddObjectexpressions adds an array of expressions to the ObjectExpressions collection
* @param {Array} expressions - an array of expressions containing ObjectExpressions in
* inline styles
*/
StyleSheets.prototype.addObjectExpressions = function (expressions) {
if (!this.objectExpressions) {
this.objectExpressions = [];
}
this.objectExpressions = this.objectExpressions.concat(expressions);
};
/**
* GetObjectExpressions returns an array of collected object expressiosn used in inline styles
* @returns {Array}
*/
StyleSheets.prototype.getObjectExpressions = function () {
return this.objectExpressions;
};
let currentContent;
const getSourceCode = node => currentContent
.getSourceCode(node)
.getText(node);
const astHelpers = {
containsStyleSheetObject: function (node) {
return Boolean(
node &&
node.init &&
node.init.callee &&
node.init.callee.object &&
node.init.callee.object.name === 'StyleSheet'
);
},
containsCreateCall: function (node) {
return Boolean(
node &&
node.init &&
node.init.callee &&
node.init.callee.property &&
node.init.callee.property.name === 'create'
);
},
isStyleSheetDeclaration: function (node) {
return Boolean(
astHelpers.containsStyleSheetObject(node) &&
astHelpers.containsCreateCall(node)
);
},
getStyleSheetName: function (node) {
if (
node &&
node.id
) {
return node.id.name;
}
},
getStyleDeclarations: function (node) {
if (
node &&
node.init &&
node.init.arguments &&
node.init.arguments[0] &&
node.init.arguments[0].properties
) {
return node
.init
.arguments[0]
.properties
.filter(property => property.type === 'Property');
}
return [];
},
isStyleAttribute: function (node) {
return Boolean(
node.type === 'JSXAttribute' &&
node.name &&
node.name.name &&
node.name.name.toLowerCase().includes('style')
);
},
collectStyleObjectExpressions: function (node, context) {
currentContent = context;
if (astHelpers.hasArrayOfStyleReferences(node)) {
const styleReferenceContainers = node
.expression
.elements;
return astHelpers.collectStyleObjectExpressionFromContainers(
styleReferenceContainers
);
} else if (node && node.expression) {
return astHelpers.getStyleObjectExpressionFromNode(node.expression);
}
return [];
},
collectColorLiterals: function (node, context) {
if (!node) {
return [];
}
currentContent = context;
if (astHelpers.hasArrayOfStyleReferences(node)) {
const styleReferenceContainers = node
.expression
.elements;
return astHelpers.collectColorLiteralsFromContainers(
styleReferenceContainers
);
}
if (node.type === 'ObjectExpression') {
return astHelpers.getColorLiteralsFromNode(node);
}
return astHelpers.getColorLiteralsFromNode(node.expression);
},
collectStyleObjectExpressionFromContainers: function (nodes) {
let objectExpressions = [];
nodes.forEach((node) => {
objectExpressions = objectExpressions
.concat(astHelpers.getStyleObjectExpressionFromNode(node));
});
return objectExpressions;
},
collectColorLiteralsFromContainers: function (nodes) {
let colorLiterals = [];
nodes.forEach((node) => {
colorLiterals = colorLiterals
.concat(astHelpers.getColorLiteralsFromNode(node));
});
return colorLiterals;
},
getStyleReferenceFromNode: function (node) {
let styleReference;
let leftStyleReferences;
let rightStyleReferences;
if (!node) {
return [];
}
switch (node.type) {
case 'MemberExpression':
styleReference = astHelpers.getStyleReferenceFromExpression(node);
return [styleReference];
case 'LogicalExpression':
leftStyleReferences = astHelpers.getStyleReferenceFromNode(node.left);
rightStyleReferences = astHelpers.getStyleReferenceFromNode(node.right);
return [].concat(leftStyleReferences).concat(rightStyleReferences);
case 'ConditionalExpression':
leftStyleReferences = astHelpers.getStyleReferenceFromNode(node.consequent);
rightStyleReferences = astHelpers.getStyleReferenceFromNode(node.alternate);
return [].concat(leftStyleReferences).concat(rightStyleReferences);
default:
return [];
}
},
getStyleObjectExpressionFromNode: function (node) {
let leftStyleObjectExpression;
let rightStyleObjectExpression;
if (!node) {
return [];
}
if (node.type === 'ObjectExpression') {
return [astHelpers.getStyleObjectFromExpression(node)];
}
switch (node.type) {
case 'LogicalExpression':
leftStyleObjectExpression = astHelpers.getStyleObjectExpressionFromNode(node.left);
rightStyleObjectExpression = astHelpers.getStyleObjectExpressionFromNode(node.right);
return [].concat(leftStyleObjectExpression).concat(rightStyleObjectExpression);
case 'ConditionalExpression':
leftStyleObjectExpression = astHelpers.getStyleObjectExpressionFromNode(node.consequent);
rightStyleObjectExpression = astHelpers.getStyleObjectExpressionFromNode(node.alternate);
return [].concat(leftStyleObjectExpression).concat(rightStyleObjectExpression);
default:
return [];
}
},
getColorLiteralsFromNode: function (node) {
let leftColorLiterals;
let rightColorLiterals;
if (!node) {
return [];
}
if (node.type === 'ObjectExpression') {
return [astHelpers.getColorLiteralsFromExpression(node)];
}
switch (node.type) {
case 'LogicalExpression':
leftColorLiterals = astHelpers.getColorLiteralsFromNode(node.left);
rightColorLiterals = astHelpers.getColorLiteralsFromNode(node.right);
return [].concat(leftColorLiterals).concat(rightColorLiterals);
case 'ConditionalExpression':
leftColorLiterals = astHelpers.getColorLiteralsFromNode(node.consequent);
rightColorLiterals = astHelpers.getColorLiteralsFromNode(node.alternate);
return [].concat(leftColorLiterals).concat(rightColorLiterals);
default:
return [];
}
},
hasArrayOfStyleReferences: function (node) {
return node && Boolean(
node.type === 'JSXExpressionContainer' &&
node.expression &&
node.expression.type === 'ArrayExpression'
);
},
getStyleReferenceFromExpression: function (node) {
const result = [];
const name = astHelpers.getObjectName(node);
if (name) {
result.push(name);
}
const property = astHelpers.getPropertyName(node);
if (property) {
result.push(property);
}
return result.join('.');
},
getStyleObjectFromExpression: function (node) {
const obj = {};
let invalid = false;
if (node.properties && node.properties.length) {
node.properties.forEach((p) => {
if (!p.value || !p.key) {
return;
}
if (p.value.type === 'Literal') {
invalid = true;
obj[p.key.name] = p.value.value;
} else if (p.value.type === 'ConditionalExpression') {
const innerNode = p.value;
if (innerNode.consequent.type === 'Literal' || innerNode.alternate.type === 'Literal') {
invalid = true;
obj[p.key.name] = getSourceCode(innerNode);
}
} else if (p.value.type === 'UnaryExpression' && p.value.operator === '-') {
invalid = true;
obj[p.key.name] = -1 * p.value.argument.value;
} else if (p.value.type === 'UnaryExpression' && p.value.operator === '+') {
invalid = true;
obj[p.key.name] = p.value.argument.value;
}
});
}
return invalid ? { expression: obj, node: node } : undefined;
},
getColorLiteralsFromExpression: function (node) {
const obj = {};
let invalid = false;
if (node.properties && node.properties.length) {
node.properties.forEach((p) => {
if (p.key && p.key.name && p.key.name.toLowerCase().indexOf('color') !== -1) {
if (p.value.type === 'Literal') {
invalid = true;
obj[p.key.name] = p.value.value;
} else if (p.value.type === 'ConditionalExpression') {
const innerNode = p.value;
if (innerNode.consequent.type === 'Literal' || innerNode.alternate.type === 'Literal') {
invalid = true;
obj[p.key.name] = getSourceCode(innerNode);
}
}
}
});
}
return invalid ? { expression: obj, node: node } : undefined;
},
getObjectName: function (node) {
if (
node &&
node.object &&
node.object.name
) {
return node.object.name;
}
},
getPropertyName: function (node) {
if (
node &&
node.property &&
node.property.name
) {
return node.property.name;
}
},
getPotentialStyleReferenceFromMemberExpression: function (node) {
if (
node &&
node.object &&
node.object.type === 'Identifier' &&
node.object.name &&
node.property &&
node.property.type === 'Identifier' &&
node.property.name &&
node.parent.type !== 'MemberExpression'
) {
return [node.object.name, node.property.name].join('.');
}
},
};
module.exports.astHelpers = astHelpers;
module.exports.StyleSheets = StyleSheets;

View File

@@ -0,0 +1,92 @@
/**
* @fileoverview Utility functions for React components detection
* @author Yannick Croissant
*/
'use strict';
/**
* Record that a particular variable has been used in code
*
* @param {String} name The name of the variable to mark as used.
* @returns {Boolean} True if the variable was found and marked as used, false if not.
*/
function markVariableAsUsed(context, name) {
let scope = context.getScope();
let variables;
let i;
let len;
let found = false;
// Special Node.js scope means we need to start one level deeper
if (scope.type === 'global') {
while (scope.childScopes.length) {
scope = scope.childScopes[0];
}
}
do {
variables = scope.variables;
for (i = 0, len = variables.length; i < len; i++) { // eslint-disable-line no-plusplus
if (variables[i].name === name) {
variables[i].eslintUsed = true;
found = true;
}
}
scope = scope.upper;
} while (scope);
return found;
}
/**
* Search a particular variable in a list
* @param {Array} variables The variables list.
* @param {Array} name The name of the variable to search.
* @returns {Boolean} True if the variable was found, false if not.
*/
function findVariable(variables, name) {
let i;
let len;
for (i = 0, len = variables.length; i < len; i++) { // eslint-disable-line no-plusplus
if (variables[i].name === name) {
return true;
}
}
return false;
}
/**
* List all variable in a given scope
*
* Contain a patch for babel-eslint to avoid https://github.com/babel/babel-eslint/issues/21
*
* @param {Object} context The current rule context.
* @param {Array} name The name of the variable to search.
* @returns {Boolean} True if the variable was found, false if not.
*/
function variablesInScope(context) {
let scope = context.getScope();
let variables = scope.variables;
while (scope.type !== 'global') {
scope = scope.upper;
variables = scope.variables.concat(variables);
}
if (scope.childScopes.length) {
variables = scope.childScopes[0].variables.concat(variables);
if (scope.childScopes[0].childScopes.length) {
variables = scope.childScopes[0].childScopes[0].variables.concat(variables);
}
}
return variables;
}
module.exports = {
findVariable: findVariable,
variablesInScope: variablesInScope,
markVariableAsUsed: markVariableAsUsed,
};

109
node_modules/eslint-plugin-react-native/package.json generated vendored Normal file
View File

@@ -0,0 +1,109 @@
{
"_args": [
[
"eslint-plugin-react-native@^3.2.1",
"/home/bernhard/freifunk-app/node_modules/react-native"
]
],
"_from": "eslint-plugin-react-native@>=3.2.1 <4.0.0",
"_id": "eslint-plugin-react-native@3.2.1",
"_inCache": true,
"_installable": true,
"_location": "/eslint-plugin-react-native",
"_nodeVersion": "6.5.0",
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/eslint-plugin-react-native-3.2.1.tgz_1515656328953_0.48320798948407173"
},
"_npmUser": {
"email": "tom@intellicode.nl",
"name": "tomhastjarjanto"
},
"_npmVersion": "5.4.0",
"_phantomChildren": {},
"_requested": {
"name": "eslint-plugin-react-native",
"raw": "eslint-plugin-react-native@^3.2.1",
"rawSpec": "^3.2.1",
"scope": null,
"spec": ">=3.2.1 <4.0.0",
"type": "range"
},
"_requiredBy": [
"/react-native"
],
"_resolved": "https://registry.npmjs.org/eslint-plugin-react-native/-/eslint-plugin-react-native-3.2.1.tgz",
"_shasum": "04fcadd3285b7cd2f27146e640c941b00acc4e7e",
"_shrinkwrap": null,
"_spec": "eslint-plugin-react-native@^3.2.1",
"_where": "/home/bernhard/freifunk-app/node_modules/react-native",
"author": {
"email": "tom@intellicode.nl",
"name": "Tom Hastjarjanto"
},
"bugs": {
"url": "https://github.com/intellicode/eslint-plugin-react-native/issues"
},
"dependencies": {
"eslint-plugin-react-native-globals": "^0.1.1"
},
"description": "React Native specific linting rules for ESLint",
"devDependencies": {
"babel-eslint": "7.2.3",
"coveralls": "2.13.1",
"eslint": "^4.3.0",
"eslint-config-airbnb": "15.1.0",
"eslint-plugin-import": "^2.0.0",
"eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-react": "^7.3.0",
"istanbul": "0.4.5",
"mocha": "3.4.1"
},
"directories": {},
"dist": {
"integrity": "sha512-1AnJO3JUCAoLpyOEsWCwN9hPJ0aQ72OT+JvLMuHjEWYb6QWxiNOszp24CEwegMzbREtJKI9OoRqYYDYxMxmjgQ==",
"shasum": "04fcadd3285b7cd2f27146e640c941b00acc4e7e",
"tarball": "https://registry.npmjs.org/eslint-plugin-react-native/-/eslint-plugin-react-native-3.2.1.tgz"
},
"files": [
"LICENSE",
"README.md",
"index.js",
"lib"
],
"gitHead": "a6b3af51eaa919486b9ce43f61cade28f2ff63b9",
"homepage": "https://github.com/intellicode/eslint-plugin-react-native",
"keywords": [
"eslint",
"eslint-plugin",
"eslintplugin",
"react",
"react native",
"react-native"
],
"license": "MIT",
"main": "index.js",
"maintainers": [
{
"name": "tomhastjarjanto",
"email": "tom@intellicode.nl"
}
],
"name": "eslint-plugin-react-native",
"optionalDependencies": {},
"peerDependencies": {
"eslint": "^3.17.0 || ^4.0.0"
},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/intellicode/eslint-plugin-react-native.git"
},
"scripts": {
"coveralls": "cat ./reports/coverage/lcov.info | coveralls",
"lint": "eslint ./lib && eslint ./tests",
"test": "npm run lint && npm run unit-test",
"unit-test": "istanbul cover --dir reports/coverage node_modules/mocha/bin/_mocha tests/**/*.js -- --reporter dot"
},
"version": "3.2.1"
}