Comparing version 0.1.10-20190605011225.commit-d0b2a22 to 0.1.10-20190607191708.commit-28c766f
@@ -49,6 +49,7 @@ import { TokenError } from 'ebnf'; | ||
isTypeResolved: boolean; | ||
scope?: Scope; | ||
parent?: Node; | ||
private ownScope; | ||
private annotations?; | ||
constructor(astNode: ASTNode); | ||
scope: Scope | undefined; | ||
/** Name of the node constructor */ | ||
@@ -199,3 +200,3 @@ readonly nodeName: string; | ||
constructor(astNode: ASTNode, reference: ReferenceNode, directives: DirectiveNode[]); | ||
readonly childrenOrEmpty: (ReferenceNode | DecoratorNode | DirectiveNode)[]; | ||
readonly childrenOrEmpty: (ReferenceNode | DirectiveNode | DecoratorNode)[]; | ||
} | ||
@@ -202,0 +203,0 @@ class ImportDirectiveNode extends DirectiveNode { |
@@ -41,2 +41,12 @@ "use strict"; | ||
} | ||
get scope() { | ||
if (this.ownScope) | ||
return this.ownScope; | ||
if (this.parent) | ||
return this.parent.scope; | ||
return undefined; | ||
} | ||
set scope(scope) { | ||
this.ownScope = scope; | ||
} | ||
/** Name of the node constructor */ | ||
@@ -43,0 +53,0 @@ get nodeName() { |
@@ -191,5 +191,8 @@ "use strict"; | ||
const typeName = 'boolean'; | ||
if (!node.scope.canResolveName(typeName)) { | ||
throw new NodeError_1.LysScopeError(`Cannot find name '${typeName}' ` + node.scope.inspect(), node); | ||
try { | ||
node.scope.get(typeName); | ||
} | ||
catch (e) { | ||
throw new NodeError_1.LysScopeError(e.toString(), node); | ||
} | ||
const resolved = node.scope.get(typeName); | ||
@@ -200,5 +203,8 @@ node.booleanReference = resolved; | ||
else if (node instanceof nodes_1.Nodes.LiteralNode) { | ||
if (!node.scope.canResolveName(node.typeName)) { | ||
throw new NodeError_1.LysScopeError(`Cannot find name '${node.typeName}' ` + node.scope.inspect(), node); | ||
try { | ||
node.scope.get(node.typeName); | ||
} | ||
catch (e) { | ||
throw new NodeError_1.LysScopeError(e.toString(), node); | ||
} | ||
const resolved = node.scope.get(node.typeName); | ||
@@ -209,5 +215,8 @@ node.resolvedReference = resolved; | ||
else if (node instanceof nodes_1.Nodes.ReferenceNode) { | ||
if (!node.scope.canResolveQName(node.variable)) { | ||
throw new NodeError_1.LysScopeError(`Cannot find name '${node.variable.text}' ` + node.scope.inspect(), node.variable); | ||
try { | ||
node.scope.getQName(node.variable); | ||
} | ||
catch (e) { | ||
throw new NodeError_1.LysScopeError(e.toString(), node.variable); | ||
} | ||
const resolved = node.scope.getQName(node.variable); | ||
@@ -263,2 +272,3 @@ const document = helpers_1.getDocument(node); | ||
const member = new nodes_1.Nodes.MemberNode(node.functionNode.astNode, node.functionNode, '.', new nodes_1.Nodes.NameIdentifierNode(node.functionNode.astNode, 'apply')); | ||
member.scope = node.functionNode.scope; | ||
node.functionNode = member; | ||
@@ -265,0 +275,0 @@ } |
@@ -18,2 +18,3 @@ import { Nodes } from './nodes'; | ||
constructor(parsingContext: ParsingContext, moduleName: string, parent?: Scope | null, nameHint?: string); | ||
isDescendantOf(parentScope: Scope): boolean; | ||
registerForeginModule(moduleName: string): Set<string>; | ||
@@ -20,0 +21,0 @@ registerImport(moduleName: string, names: Set<string>): void; |
@@ -22,2 +22,11 @@ "use strict"; | ||
} | ||
isDescendantOf(parentScope) { | ||
if (this.parent) { | ||
if (parentScope === this.parent) { | ||
return true; | ||
} | ||
return this.parent.isDescendantOf(parentScope); | ||
} | ||
return false; | ||
} | ||
registerForeginModule(moduleName) { | ||
@@ -88,3 +97,3 @@ if (moduleName && !this.importedModules.has(moduleName)) { | ||
if (!this.canGetFromOutside(localName)) { | ||
throw new Error(`Name ${localName} is private in module ${this.name}`); | ||
throw new Error(`Name "${localName}" is private in module "${this.moduleName}"`); | ||
} | ||
@@ -91,0 +100,0 @@ return this.nameMappings[localName]; |
@@ -149,6 +149,6 @@ "use strict"; | ||
if (type.of instanceof types_1.TypeAlias) { | ||
const fnType = typeHelpers_1.resolveTypeMember(node, type.of, 'apply', this.messageCollector); | ||
const fnType = typeHelpers_1.resolveTypeMember(node, type.of, 'apply', this.messageCollector, node.scope); | ||
// TODO: a better error would be X is not callable | ||
if (fnType) { | ||
const fun = typeHelpers_1.findFunctionOverload(fnType.type, [], node, null, false, this.messageCollector, true); | ||
const fun = typeHelpers_1.findFunctionOverload(fnType.type, [], node, null, false, this.messageCollector, true, node.scope); | ||
if (typeHelpers_1.isValidType(fun) && fun instanceof types_1.FunctionType) { | ||
@@ -181,3 +181,3 @@ typeHelpers_1.annotateImplicitCall(node, fun, [], this.messageCollector); | ||
else { | ||
this.messageCollector.errorIfBranchDoesntHaveAny('Unable to resolve name 2', node); | ||
this.messageCollector.errorIfBranchDoesntHaveAny('Unable to resolve name', node); | ||
} | ||
@@ -203,5 +203,5 @@ } | ||
} | ||
const valueType = typeHelpers_1.resolveTypeMember(node.rhs, rhsType, 'is', this.messageCollector); | ||
const valueType = typeHelpers_1.resolveTypeMember(node.rhs, rhsType, 'is', this.messageCollector, node.scope); | ||
if (valueType) { | ||
const fun = typeHelpers_1.findFunctionOverload(valueType.type, [rhsType], node, null, false, this.messageCollector, false); | ||
const fun = typeHelpers_1.findFunctionOverload(valueType.type, [rhsType], node, null, false, this.messageCollector, false, node.scope); | ||
if (fun instanceof types_1.FunctionType) { | ||
@@ -243,5 +243,5 @@ node.resolvedFunctionType = fun; | ||
} | ||
const memberType = typeHelpers_1.resolveTypeMember(node.lhs, lhsType, 'as', this.messageCollector); | ||
const memberType = typeHelpers_1.resolveTypeMember(node.lhs, lhsType, 'as', this.messageCollector, node.scope); | ||
if (memberType) { | ||
const fun = typeHelpers_1.findFunctionOverload(memberType.type, [lhsType], node, rhsType, false, new MessageCollector_1.MessageCollector(), false); | ||
const fun = typeHelpers_1.findFunctionOverload(memberType.type, [lhsType], node, rhsType, false, new MessageCollector_1.MessageCollector(), false, node.scope); | ||
if (fun instanceof types_1.FunctionType && typeHelpers_1.isValidType(fun.returnType)) { | ||
@@ -270,3 +270,3 @@ node.resolvedFunctionType = fun; | ||
const memberName = node.operator.name; | ||
const memberType = typeHelpers_1.resolveTypeMember(node, lhsType, memberName, this.messageCollector); | ||
const memberType = typeHelpers_1.resolveTypeMember(node, lhsType, memberName, this.messageCollector, node.scope); | ||
if (memberType) { | ||
@@ -299,3 +299,3 @@ if (typeHelpers_1.isValidType(rhsType)) { | ||
const memberName = node.operator.name; | ||
const memberType = typeHelpers_1.resolveTypeMember(node, rhsType, memberName, this.messageCollector); | ||
const memberType = typeHelpers_1.resolveTypeMember(node, rhsType, memberName, this.messageCollector, node.scope); | ||
if (memberType) { | ||
@@ -366,3 +366,3 @@ const argTypes = [rhsType]; | ||
const memberLhsType = this.getType(node.lhs.lhs); | ||
const fun = typeHelpers_1.findFunctionOverload(lhsType, [memberLhsType, rhsType], node.lhs, null, false, this.messageCollector, true); | ||
const fun = typeHelpers_1.findFunctionOverload(lhsType, [memberLhsType, rhsType], node.lhs, null, false, this.messageCollector, true, node.scope); | ||
if (typeHelpers_1.isValidType(fun) && fun instanceof types_1.FunctionType) { | ||
@@ -393,3 +393,3 @@ typeHelpers_1.annotateImplicitCall(node, fun, [node.lhs.lhs, node.rhs], this.messageCollector); | ||
} | ||
const fun = typeHelpers_1.findFunctionOverload(lhsType, [memberLhsType, memberRhsType, rhsType], node.lhs, null, false, this.messageCollector, true); | ||
const fun = typeHelpers_1.findFunctionOverload(lhsType, [memberLhsType, memberRhsType, rhsType], node.lhs, null, false, this.messageCollector, true, node.scope); | ||
if (typeHelpers_1.isValidType(fun) && fun instanceof types_1.FunctionType) { | ||
@@ -554,3 +554,3 @@ typeHelpers_1.annotateImplicitCall(node, fun, [node.lhs.lhs, node.lhs.rhs, node.rhs], this.messageCollector); | ||
const memberName = node.memberName.name; | ||
const memberType = typeHelpers_1.resolveTypeMember(node.memberName, lhsType.of, memberName, this.messageCollector); | ||
const memberType = typeHelpers_1.resolveTypeMember(node.memberName, lhsType.of, memberName, this.messageCollector, node.scope); | ||
if (memberType) { | ||
@@ -573,7 +573,7 @@ if (node.hasAnnotation(annotations_1.annotations.IsValueNode)) { | ||
const memberName = 'property_' + node.memberName.name; | ||
const memberType = typeHelpers_1.resolveTypeMember(node.memberName, lhsType, memberName, this.messageCollector); | ||
const memberType = typeHelpers_1.resolveTypeMember(node.memberName, lhsType, memberName, this.messageCollector, node.scope); | ||
if (memberType) { | ||
const isGetter = !node.hasAnnotation(annotations_1.annotations.IsAssignationLHS); | ||
if (isGetter) { | ||
const fun = typeHelpers_1.findFunctionOverload(memberType.type, [lhsType], node, null, false, this.messageCollector, false); | ||
const fun = typeHelpers_1.findFunctionOverload(memberType.type, [lhsType], node, null, false, this.messageCollector, false, node.scope); | ||
if (typeHelpers_1.isValidType(fun) && fun instanceof types_1.FunctionType) { | ||
@@ -714,6 +714,6 @@ typeHelpers_1.annotateImplicitCall(node, fun, [node.lhs], this.messageCollector); | ||
} | ||
const eqFunction = typeHelpers_1.resolveTypeMember(node.literal, carryType, '==', this.messageCollector); | ||
const eqFunction = typeHelpers_1.resolveTypeMember(node.literal, carryType, '==', this.messageCollector, node.scope); | ||
if (eqFunction) { | ||
const argTypes = [carryType, argumentType]; | ||
const fun = typeHelpers_1.findFunctionOverload(eqFunction.type, argTypes, node.literal, null, false, new MessageCollector_1.MessageCollector(), true); | ||
const fun = typeHelpers_1.findFunctionOverload(eqFunction.type, argTypes, node.literal, null, false, new MessageCollector_1.MessageCollector(), true, node.scope); | ||
if (typeHelpers_1.isValidType(fun) && fun instanceof types_1.FunctionType) { | ||
@@ -749,5 +749,5 @@ node.resolvedFunctionType = fun; | ||
else { | ||
const eqFunction = typeHelpers_1.resolveTypeMember(node.typeReference, argumentType, 'is', this.messageCollector); | ||
const eqFunction = typeHelpers_1.resolveTypeMember(node.typeReference, argumentType, 'is', this.messageCollector, node.scope); | ||
if (eqFunction) { | ||
const fun = typeHelpers_1.findFunctionOverload(eqFunction.type, [argumentType], node, null, false, new MessageCollector_1.MessageCollector(), false); | ||
const fun = typeHelpers_1.findFunctionOverload(eqFunction.type, [argumentType], node, null, false, new MessageCollector_1.MessageCollector(), false, node.scope); | ||
if (typeHelpers_1.isValidType(fun) && fun instanceof types_1.FunctionType) { | ||
@@ -754,0 +754,0 @@ node.resolvedFunctionType = fun; |
import { FunctionType, Type } from '../types'; | ||
import { Nodes } from '../nodes'; | ||
import { MessageCollector } from '../MessageCollector'; | ||
import { Scope } from '../Scope'; | ||
export declare function isValidType(type: Type | null | void): type is Type; | ||
export declare function getTypeTypeType(node: Nodes.Node, type: Type | null, messageCollector: MessageCollector): Type | null; | ||
export declare function getTypeFromTypeNode(node: Nodes.Node, messageCollector: MessageCollector): Type | null; | ||
export declare function resolveTypeMember(errorNode: Nodes.Node | null, type: Type, memberName: string, messageCollector: MessageCollector): { | ||
export declare function resolveTypeMember(errorNode: Nodes.Node | null, type: Type, memberName: string, messageCollector: MessageCollector, scope: Scope | undefined): { | ||
type: Type; | ||
@@ -12,3 +13,3 @@ referencedNode?: Nodes.NameIdentifierNode; | ||
export declare function processFunctionCall(node: Nodes.AbstractFunctionCallNode, functionType: Type, argTypes: Type[], messageCollector: MessageCollector): Type | null; | ||
export declare function findFunctionOverload(incommingType: Type, argTypes: Type[], errorNode: Nodes.Node | null, returnType: Type | null, strict: boolean, messageCollector: MessageCollector, automaticCoercion: boolean): Type | null; | ||
export declare function findFunctionOverload(incommingType: Type, argTypes: Type[], errorNode: Nodes.Node | null, returnType: Type | null, strict: boolean, messageCollector: MessageCollector, automaticCoercion: boolean, scope: Scope | undefined): Type | null; | ||
export declare function canBeAssigned(sourceType: Type, targetType: Type): boolean; | ||
@@ -15,0 +16,0 @@ export declare function ensureCanBeAssignedWithImplicitConversion(sourceType: Type, targetType: Type, node: Nodes.ExpressionNode, messageCollector: MessageCollector): { |
@@ -57,3 +57,3 @@ "use strict"; | ||
exports.getTypeFromTypeNode = getTypeFromTypeNode; | ||
function resolveTypeMember(errorNode, type, memberName, messageCollector) { | ||
function resolveTypeMember(errorNode, type, memberName, messageCollector, scope) { | ||
if (type && type instanceof types_1.TypeAlias) { | ||
@@ -63,2 +63,27 @@ const resolvedName = type.name.namespaceNames && type.name.namespaceNames.get(memberName); | ||
const memberType = types_1.TypeHelpers.getNodeType(resolvedName); | ||
const parent = resolvedName.parent; | ||
if (parent && parent instanceof nodes_1.Nodes.DirectiveNode) { | ||
if (!parent.isPublic) { | ||
const declScope = resolvedName.scope; | ||
if (!declScope) { | ||
if (errorNode) { | ||
messageCollector.error(new NodeError_1.LysTypeError(`Name's parent has no scope`, type.name)); | ||
} | ||
return false; | ||
} | ||
if (!scope) { | ||
if (errorNode) { | ||
messageCollector.error(new NodeError_1.LysTypeError(`Scope is null`, errorNode)); | ||
console.trace(); | ||
} | ||
return false; | ||
} | ||
if (!scope.isDescendantOf(declScope)) { | ||
if (errorNode) { | ||
messageCollector.error(new NodeError_1.LysTypeError(`Name "${memberName}" is private in ${type.name.name}`, errorNode)); | ||
} | ||
return false; | ||
} | ||
} | ||
} | ||
if (isValidType(memberType)) { | ||
@@ -103,3 +128,3 @@ return { type: memberType, referencedNode: resolvedName }; | ||
if (isGetter) { | ||
const fun = findFunctionOverload(functionType, argTypes, node, null, false, messageCollector, true); | ||
const fun = findFunctionOverload(functionType, argTypes, node, null, false, messageCollector, true, node.scope); | ||
if (fun instanceof types_1.FunctionType) { | ||
@@ -126,5 +151,5 @@ node.resolvedFunctionType = fun; | ||
exports.processFunctionCall = processFunctionCall; | ||
function findFunctionOverload(incommingType, argTypes, errorNode, returnType, strict, messageCollector, automaticCoercion) { | ||
function findFunctionOverload(incommingType, argTypes, errorNode, returnType, strict, messageCollector, automaticCoercion, scope) { | ||
if (incommingType instanceof types_1.TypeType) { | ||
return findFunctionOverload(incommingType.of, argTypes, errorNode, returnType, strict, messageCollector, automaticCoercion); | ||
return findFunctionOverload(incommingType.of, argTypes, errorNode, returnType, strict, messageCollector, automaticCoercion, scope); | ||
} | ||
@@ -136,3 +161,3 @@ if (incommingType instanceof types_1.IntersectionType) { | ||
if (strict) { | ||
if (acceptsTypes(fun, argTypes, strict, automaticCoercion)) { | ||
if (acceptsTypes(fun, argTypes, strict, automaticCoercion, scope)) { | ||
if (!returnType || fun.returnType.equals(returnType)) { | ||
@@ -144,3 +169,3 @@ return fun; | ||
else { | ||
const result = acceptsTypes(fun, argTypes, strict, automaticCoercion); | ||
const result = acceptsTypes(fun, argTypes, strict, automaticCoercion, scope); | ||
if (result) { | ||
@@ -201,3 +226,3 @@ if (!returnType || canBeAssigned(fun.returnType, returnType)) { | ||
else if (incommingType instanceof types_1.FunctionType) { | ||
const queryResult = acceptsTypes(incommingType, argTypes, strict, automaticCoercion); | ||
const queryResult = acceptsTypes(incommingType, argTypes, strict, automaticCoercion, scope); | ||
if (!queryResult) { | ||
@@ -221,3 +246,3 @@ if (errorNode) { | ||
exports.findFunctionOverload = findFunctionOverload; | ||
function findImplicitTypeCasting(errorNode, from, to, messageCollector) { | ||
function findImplicitTypeCasting(errorNode, from, to, messageCollector, scope) { | ||
if (canBeAssigned(from, to)) { | ||
@@ -228,5 +253,5 @@ return null; | ||
try { | ||
const fnType = resolveTypeMember(errorNode, from, 'as', messageCollector); | ||
const fnType = resolveTypeMember(errorNode, from, 'as', messageCollector, scope); | ||
if (fnType) { | ||
const fun = findFunctionOverload(fnType.type, [from], null, to, true, messageCollector, true); | ||
const fun = findFunctionOverload(fnType.type, [from], null, to, true, messageCollector, true, scope); | ||
if (fun instanceof types_1.FunctionType) { | ||
@@ -264,3 +289,3 @@ if (!fun.name.hasAnnotation(annotations_1.annotations.Explicit)) { | ||
} | ||
function acceptsTypes(type, types, strict, automaticCoercion) { | ||
function acceptsTypes(type, types, strict, automaticCoercion, scope) { | ||
if (type.parameterTypes.length !== types.length) { | ||
@@ -289,3 +314,3 @@ return null; | ||
try { | ||
const implicitCast = findImplicitTypeCasting(null, argumentType, parameterType, new MessageCollector_1.MessageCollector()); | ||
const implicitCast = findImplicitTypeCasting(null, argumentType, parameterType, new MessageCollector_1.MessageCollector(), scope); | ||
if (implicitCast) { | ||
@@ -367,3 +392,3 @@ casts.push(implicitCast); | ||
else { | ||
const implicitCast = findImplicitTypeCasting(node, sourceType, targetType, new MessageCollector_1.MessageCollector()); | ||
const implicitCast = findImplicitTypeCasting(node, sourceType, targetType, new MessageCollector_1.MessageCollector(), node.scope); | ||
if (implicitCast) { | ||
@@ -370,0 +395,0 @@ return { node: createImplicitCall(node, implicitCast, [node], messageCollector), type: targetType }; |
{ | ||
"name": "lys", | ||
"version": "0.1.10-20190605011225.commit-d0b2a22", | ||
"version": "0.1.10-20190607191708.commit-28c766f", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
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
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
847710
9655