Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@fimbul/mimir

Package Overview
Dependencies
Maintainers
2
Versions
125
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fimbul/mimir - npm Package Compare versions

Comparing version 0.23.0-dev.20210114 to 0.23.0-dev.20210116

2

package.json
{
"name": "@fimbul/mimir",
"version": "0.23.0-dev.20210114",
"version": "0.23.0-dev.20210116",
"description": "Core rules of the Fimbullinter project",

@@ -5,0 +5,0 @@ "main": "recommended.yaml",

@@ -6,9 +6,17 @@ "use strict";

const tsutils_1 = require("tsutils");
function getRestrictedElementAccessError(checker, symbol, name, node, lhsType) {
function getRestrictedElementAccessError(checker, symbol, name, node, lhsType, compilerOptions) {
const flags = getModifierFlagsOfSymbol(symbol);
if (node.expression.kind === ts.SyntaxKind.ThisKeyword &&
flags & ts.ModifierFlags.Abstract && hasNonPrototypeDeclaration(symbol)) {
const enclosingClass = getEnclosingClassOfAbstractPropertyAccess(node.parent);
if (enclosingClass !== undefined)
return `Abstract property '${name}' in class '${printClass(enclosingClass, checker)}' cannot be accessed during class initialization.`;
if (node.expression.kind === ts.SyntaxKind.ThisKeyword && hasNonPrototypeDeclaration(symbol)) {
const useDuringClassInitialization = getPropertyDeclarationOrConstructorAccessingProperty(node.parent);
if (useDuringClassInitialization !== undefined) {
if (flags & ts.ModifierFlags.Abstract)
return `Abstract property '${name}' in class '${printClass(tsutils_1.getSymbolOfClassLikeDeclaration(useDuringClassInitialization.parent, checker), checker)}' cannot be accessed during class initialization.`;
if (
// checking use before assign in constructor requires control flow graph
useDuringClassInitialization.kind !== ts.SyntaxKind.Constructor &&
// only checking read access
tsutils_1.getAccessKind(node) & tsutils_1.AccessKind.Read &&
isPropertyUsedBeforeAssign(symbol.valueDeclaration, useDuringClassInitialization, compilerOptions, checker))
return `Property '${name}' is used before its initialization.`;
}
}

@@ -20,3 +28,3 @@ if (node.expression.kind === ts.SyntaxKind.SuperKeyword && (flags & ts.ModifierFlags.Static) === 0 && !isStaticSuper(node)) {

symbol.declarations.every((d) => tsutils_1.hasModifier(d.modifiers, ts.SyntaxKind.AbstractKeyword)))
return `Abstract member '${name}' in class '${printClass(symbol.declarations[0].parent, checker)}' cannot be accessed via the 'super' keyword.`;
return `Abstract member '${name}' in class '${printClass(getDeclaringClassOfMember(symbol.valueDeclaration, checker), checker)}' cannot be accessed via the 'super' keyword.`;
}

@@ -26,8 +34,8 @@ if ((flags & ts.ModifierFlags.NonPublicAccessibilityModifier) === 0)

if (flags & ts.ModifierFlags.Private) {
const declaringClass = symbol.declarations[0].parent;
if (node.pos < declaringClass.pos || node.end > declaringClass.end)
const declaringClass = getDeclaringClassOfMember(symbol.valueDeclaration, checker);
if (node.pos < declaringClass.valueDeclaration.pos || node.end > declaringClass.valueDeclaration.end)
return failVisibility(name, printClass(declaringClass, checker), true);
}
else {
const declaringClasses = symbol.declarations.map((d) => d.parent);
const declaringClasses = symbol.declarations.map((d) => getDeclaringClassOfMember(d, checker).valueDeclaration);
let enclosingClass = findEnclosingClass(node.parent, declaringClasses, checker);

@@ -65,4 +73,4 @@ if (enclosingClass === undefined) {

}
function printClass(declaration, checker) {
return checker.typeToString(tsutils_1.getInstanceTypeOfClassLikeDeclaration(declaration, checker));
function printClass(symbol, checker) {
return checker.typeToString(checker.getDeclaredTypeOfSymbol(symbol));
}

@@ -130,15 +138,8 @@ function getEnclosingClassFromThisParameter(node, baseClasses, checker) {

}
function getEnclosingClassOfAbstractPropertyAccess(node) {
function getPropertyDeclarationOrConstructorAccessingProperty(node) {
while (true) {
if (tsutils_1.isFunctionScopeBoundary(node)) {
switch (node.kind) {
case ts.SyntaxKind.ClassDeclaration:
case ts.SyntaxKind.ClassExpression:
return node;
case ts.SyntaxKind.Constructor:
return node.parent;
default:
return;
}
}
if (tsutils_1.isFunctionScopeBoundary(node))
return node.kind === ts.SyntaxKind.Constructor ? node : undefined;
if (node.kind === ts.SyntaxKind.PropertyDeclaration)
return node;
node = node.parent;

@@ -210,2 +211,58 @@ }

}
function isPropertyUsedBeforeAssign(prop, usedIn, compilerOptions, checker) {
if (tsutils_1.isParameterDeclaration(prop))
// when emitting native class fields, parameter properties cannot be used in other property's initializers in the same class
return prop.parent.parent === usedIn.parent && isEmittingNativeClassFields(compilerOptions);
// this also matches assignment declarations in the same class; we could handle them, but TypeScript doesn't, so why bother
if (prop.parent !== usedIn.parent)
return false;
// property is declared before use in the same class
if (prop.pos < usedIn.pos) {
// OK if immediately initialized
if (prop.initializer !== undefined || prop.exclamationToken !== undefined)
return false;
// NOT OK if [[Define]] semantics are used, because it overrides the property from the base class
if (!tsutils_1.hasModifier(prop.modifiers, ts.SyntaxKind.DeclareKeyword) &&
tsutils_1.isCompilerOptionEnabled(compilerOptions, 'useDefineForClassFields'))
return true;
}
return tsutils_1.getBaseClassMemberOfClassElement(prop, checker) === undefined;
}
function isEmittingNativeClassFields(compilerOptions) {
return compilerOptions.target === ts.ScriptTarget.ESNext && tsutils_1.isCompilerOptionEnabled(compilerOptions, 'useDefineForClassFields');
}
function getDeclaringClassOfMember(node, checker) {
switch (node.kind) {
case ts.SyntaxKind.PropertyDeclaration: // regular property
return tsutils_1.getSymbolOfClassLikeDeclaration(node.parent, checker);
case ts.SyntaxKind.Parameter: // parameter property
return tsutils_1.getSymbolOfClassLikeDeclaration(node.parent.parent, checker);
case ts.SyntaxKind.MethodDeclaration:
case ts.SyntaxKind.GetAccessor:
case ts.SyntaxKind.SetAccessor:
if (tsutils_1.isClassLikeDeclaration(node.parent))
return tsutils_1.getSymbolOfClassLikeDeclaration(node.parent, checker);
// falls through
// JS special property assignment declarations
case ts.SyntaxKind.PropertyAssignment: // 'C.prototype = {method() {}, prop: 1, shorthand, get a() {return 1;}, set a(v) {}}
case ts.SyntaxKind.ShorthandPropertyAssignment:
return checker.getSymbolAtLocation(node.parent.parent.left.expression);
case ts.SyntaxKind.BinaryExpression: // this.foo = 1;
node = node.left;
// falls through
case ts.SyntaxKind.PropertyAccessExpression: // 'this.foo', 'C.foo' or 'C.prototype.foo'
case ts.SyntaxKind.ElementAccessExpression:
node = node.expression;
switch (node.kind) {
case ts.SyntaxKind.PropertyAccessExpression:
case ts.SyntaxKind.ElementAccessExpression:
node = node.expression;
}
return checker.getSymbolAtLocation(node);
/* istanbul ignore next */
default:
throw new Error(`unhandled property declaration kind ${node.kind}`);
// this doesn't handle access modifier: 'Object.defineProperty(C, 'foo', ...)' or 'Object.defineProperty(C.prototype, 'foo', ...)'
}
}
//# sourceMappingURL=restricted-property.js.map

@@ -25,3 +25,3 @@ "use strict";

for (const { symbol, name } of utils_1.propertiesOfType(type, names)) {
const error = restricted_property_1.getRestrictedElementAccessError(this.checker, symbol, name, node, type);
const error = restricted_property_1.getRestrictedElementAccessError(this.checker, symbol, name, node, type, this.context.compilerOptions);
if (error !== undefined)

@@ -28,0 +28,0 @@ this.addFindingAtNode(node, error);

@@ -38,3 +38,3 @@ "use strict";

}
return restricted_property_1.getRestrictedElementAccessError(this.checker, symbol, name, node, type) !== undefined;
return restricted_property_1.getRestrictedElementAccessError(this.checker, symbol, name, node, type, this.context.compilerOptions) !== undefined;
}

@@ -41,0 +41,0 @@ };

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc