From dff1450b35db3ee68fa3c0f6fa1de9cb1b8b7078 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 Oct 2019 17:00:25 +0200 Subject: [PATCH 001/172] Gather expressions from javascript & typescript --- .../src/org/jetbrains/dukat/ast/model/ast.kt | 2 + .../dukat/ast/model/nodes/ParameterNode.kt | 7 +- typescript/ts-converter/src/AstConverter.ts | 102 ++++++++++++++++-- typescript/ts-converter/src/ast/AstFactory.ts | 77 +++++++++++-- typescript/ts-converter/src/ast/ast.ts | 41 ++++++- .../ts-model-proto/src/Declarations.proto | 47 +++++++- .../dukat/tsmodel/ExpressionDeclaration.kt | 7 +- .../tsmodel/ExpressionStatementDeclaration.kt | 5 + .../expression/BinaryExpressionDeclaration.kt | 9 ++ .../IdentifierExpressionDeclaration.kt | 8 ++ .../BigIntLiteralExpressionDeclaration.kt | 5 + .../literal/LiteralExpressionDeclaration.kt | 5 + .../NumericLiteralExpressionDeclaration.kt | 5 + .../RegExLiteralExpressionDeclaration.kt | 5 + .../StringLiteralExpressionDeclaration.kt | 5 + .../dukat/tsmodel/factory/convertProtobuf.kt | 53 ++++++++- .../dukat/nodeIntroduction/introduceNodes.kt | 10 +- .../lowerings/rearrangeGeneratedEntities.kt | 2 + 18 files changed, 364 insertions(+), 31 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ExpressionStatementDeclaration.kt create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/BinaryExpressionDeclaration.kt create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/IdentifierExpressionDeclaration.kt create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/BigIntLiteralExpressionDeclaration.kt create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/LiteralExpressionDeclaration.kt create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/NumericLiteralExpressionDeclaration.kt create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/RegExLiteralExpressionDeclaration.kt create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/StringLiteralExpressionDeclaration.kt diff --git a/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/ast.kt b/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/ast.kt index f518c7300..e4fac8cd0 100644 --- a/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/ast.kt +++ b/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/ast.kt @@ -15,6 +15,7 @@ import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.EnumDeclaration import org.jetbrains.dukat.tsmodel.ExportAssignmentDeclaration +import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.GeneratedInterfaceReferenceDeclaration import org.jetbrains.dukat.tsmodel.ImportEqualsDeclaration @@ -49,6 +50,7 @@ fun Entity.duplicate(): T { is EnumDeclaration -> copy() as T is EnumNode -> copy() as T is ExportAssignmentDeclaration -> copy() as T + is ExpressionStatementDeclaration -> copy() as T is FunctionDeclaration -> copy() as T is FunctionNode -> copy() as T is FunctionTypeDeclaration -> copy() as T diff --git a/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/nodes/ParameterNode.kt b/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/nodes/ParameterNode.kt index 181930faa..17791afd4 100644 --- a/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/nodes/ParameterNode.kt +++ b/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/nodes/ParameterNode.kt @@ -2,6 +2,7 @@ package org.jetbrains.dukat.ast.model.nodes import org.jetbrains.dukat.astCommon.Entity import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration data class ParameterNode( @@ -18,10 +19,10 @@ data class ParameterNode( fun ParameterDeclaration.convertToNode(): ParameterNode = ParameterNode( name = name, type = type, - initializer = if (initializer != null) { - TypeValueNode(initializer!!.kind.value, emptyList()) + initializer = if (initializer != null && initializer is IdentifierExpressionDeclaration) { + TypeValueNode((initializer as IdentifierExpressionDeclaration).identifier, emptyList()) } else null, - meta = initializer?.meta, + meta = null, vararg = vararg, optional = optional ) \ No newline at end of file diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index 03516e007..7fc874f30 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -194,6 +194,8 @@ export class AstConverter { let typeParameterDeclarations: Array = this.convertTypeParams(functionDeclaration.typeParameters); + functionDeclaration.body + let parameterDeclarations = functionDeclaration.parameters .map( (param, count) => this.convertParameterDeclaration(param, count) @@ -309,6 +311,92 @@ export class AstConverter { } + createIdentifierExpression(name: string): Expression { + return this.astFactory.createIdentifierExpressionDeclarationAsExpression( + this.astFactory.createIdentifierDeclaration(name) + ); + } + + createBinaryExpression(left: Expression, operator: string, right: Expression): Expression { + return this.astFactory.createBinaryExpressionDeclarationAsExpression(left, operator, right); + } + + createNumericLiteralExpression(value: string): Expression { + return this.astFactory.createNumericLiteralDeclarationAsExpression(value); + } + + createBigIntLiteralExpression(value: string): Expression { + return this.astFactory.createBigIntLiteralDeclarationAsExpression(value); + } + + createStringLiteralExpression(value: string): Expression { + return this.astFactory.createStringLiteralDeclarationAsExpression(value); + } + + createRegExLiteralExpression(value: string): Expression { + return this.astFactory.createRegExLiteralDeclarationAsExpression(value); + } + + convertIdentifierExpression(expression: ts.Expression): Expression { + /*console.log('Identifier:'); + console.log('\tEscaped text: ' + expression.escapedText); + console.log('\tUnescaped text: ' + expression.getText()); + console.log('\tOriginal keyword kind: ' + expression.originalKeywordKind); + console.log('\tIs in JSDoc namespace: ' + expression.isInJSDocNamespace);*/ + + return this.createIdentifierExpression( + expression.getText() + ) + } + + convertBinaryExpression(expression: ts.Expression): Expression { + /*console.log('Binary expression:'); + console.log('\tLeft:\n' + this.convertExpression(expression.left)); + console.log('\tOperator:\n' + ts.tokenToString(expression.operatorToken)); + console.log('\tRight:\n' + this.convertExpression(expression.right));*/ + + return this.createBinaryExpression( + this.convertExpression(expression.left), + ts.tokenToString(expression.operatorToken), + this.convertExpression(expression.right) + ) + } + + convertNumericLiteralExpression(expression: ts.Expression): Expression { + return this.createNumericLiteralExpression(expression.getText()) + } + + convertBigIntLiteralExpression(expression: ts.Expression): Expression { + return this.createBigIntLiteralExpression(expression.getText()) + } + + convertStringLiteralExpression(expression: ts.Expression): Expression { + return this.createStringLiteralExpression(expression.getText()) + } + + convertRegExLiteralExpression(expression: ts.Expression): Expression { + return this.createRegExLiteralExpression(expression.getText()) + } + + convertExpression(expression: ts.Expression): Expression { + if(ts.isBinaryExpression(expression)) { + return this.convertBinaryExpression(expression); + } else if(ts.isIdentifier(expression)) { + return this.convertIdentifierExpression(expression); + } else if(ts.isNumericLiteral(expression)) { + return this.convertNumericLiteralExpression(expression); + } else if(ts.isBigIntLiteral(expression)) { + return this.convertBigIntLiteralExpression(expression); + } else if(ts.isStringLiteral(expression)) { + return this.convertStringLiteralExpression(expression); + } else if(ts.isRegularExpressionLiteral(expression)) { + return this.convertRegExLiteralExpression(expression); + } else { + return this.createIdentifierExpression('/* ' + expression.getText() + ' */') + } + } + + createIntersectionType(params: Array) { return this.astFactory.createIntersectionTypeDeclaration(params); } @@ -437,14 +525,12 @@ export class AstConverter { let initializer: Expression | null = null; if (param.initializer != null) { // TODO: this never happens in tests and I should add one - initializer = this.astFactory.createExpression( - this.astFactory.createTypeDeclaration(this.astFactory.createIdentifierDeclarationAsNameEntity("definedExternally"), []), - param.initializer.getText() + initializer = this.createIdentifierExpression( + "definedExternally", ) } else if (param.questionToken != null) { - initializer = this.astFactory.createExpression( - this.astFactory.createTypeDeclaration(this.astFactory.createIdentifierDeclarationAsNameEntity("definedExternally"), []), - "null" + initializer = this.createIdentifierExpression( + "definedExternally", ) } @@ -790,6 +876,10 @@ export class AstConverter { this.exportContext.getUID(declaration) )); } + } else if (ts.isExpressionStatement(statement)) { + res.push(this.astFactory.createExpressionStatement( + this.convertExpression(statement.expression) + )); } else if (ts.isTypeAliasDeclaration(statement)) { if (ts.isTypeLiteralNode(statement.type)) { res.push(this.convertTypeLiteralToInterfaceDeclaration( diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index 3ff13271d..2fa16340d 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -1,5 +1,6 @@ import * as declarations from "declarations"; import { + BinaryExpression, CallSignatureDeclaration, ClassDeclaration, ClassLikeDeclaration, @@ -10,20 +11,21 @@ import { EnumTokenDeclaration, ExportAssignmentDeclaration, Expression, + ExpressionStatement, FunctionDeclaration, FunctionTypeDeclaration, HeritageClauseDeclaration, - IdentifierEntity, + IdentifierEntity, IdentifierExpression, ImportEqualsDeclaration, IndexSignatureDeclaration, InterfaceDeclaration, - IntersectionTypeDeclaration, + IntersectionTypeDeclaration, LiteralExpression, MemberDeclaration, MethodSignatureDeclaration, ModifierDeclaration, ModuleDeclaration, ModuleReferenceDeclaration, - NameEntity, + NameEntity, NumericLiteralExpression, ObjectLiteral, ParameterDeclaration, ParameterValue, @@ -117,14 +119,77 @@ export class AstFactory implements AstFactory { return topLevelEntity; } - createExpression(kind: TypeDeclaration, meta: string): Expression { + createExpressionStatement(expression: Expression): ExpressionStatement { + let expressionStatement = new declarations.ExpressionStatementDeclarationProto(); + expressionStatement.setExpression(expression); + + let topLevelEntity = new declarations.TopLevelEntityProto(); + topLevelEntity.setExpressionstatement(expressionStatement); + return topLevelEntity; + } + + createIdentifierExpressionDeclarationAsExpression(identifier: IdentifierEntity): IdentifierExpression { + let identifierExpressionProto = new declarations.IdentifierExpressionDeclarationProto(); + identifierExpressionProto.setIdentifier(identifier); + let expression = new declarations.ExpressionDeclarationProto(); - expression.setKind(kind); - expression.setMeta(meta); + expression.setIdentifierexpression(identifierExpressionProto); + return expression; + } + + createBinaryExpressionDeclarationAsExpression(left: Expression, operator: string, right: Expression): BinaryExpression { + let binaryExpression = new declarations.BinaryExpressionDeclarationProto(); + binaryExpression.setLeft(left); + binaryExpression.setOperator(operator); + binaryExpression.setRight(right); + + let expression = new declarations.ExpressionDeclarationProto(); + expression.setBinaryexpression(binaryExpression); + return expression; + } + private asExpression(literalExpression: LiteralExpression): Expression { + let expression = new declarations.ExpressionDeclarationProto(); + expression.setLiteralexpression(literalExpression); return expression; } + createNumericLiteralDeclarationAsExpression(value: string): Expression { + let numericLiteralExpression = new declarations.NumericLiteralExpressionDeclarationProto(); + numericLiteralExpression.setValue(value); + + let literalExpression = new declarations.LiteralExpressionDeclarationProto(); + literalExpression.setNumericliteral(numericLiteralExpression); + return this.asExpression(literalExpression); + } + + createBigIntLiteralDeclarationAsExpression(value: string): Expression { + let bigIntLiteralExpression = new declarations.BigIntLiteralExpressionDeclarationProto(); + bigIntLiteralExpression.setValue(value); + + let literalExpression = new declarations.LiteralExpressionDeclarationProto(); + literalExpression.setBigintliteral(bigIntLiteralExpression); + return this.asExpression(literalExpression); + } + + createStringLiteralDeclarationAsExpression(value: string): Expression { + let stringLiteralExpression = new declarations.StringLiteralExpressionDeclarationProto(); + stringLiteralExpression.setValue(value); + + let literalExpression = new declarations.LiteralExpressionDeclarationProto(); + literalExpression.setStringliteral(stringLiteralExpression); + return this.asExpression(literalExpression); + } + + createRegExLiteralDeclarationAsExpression(value: string): Expression { + let regExLiteralExpression = new declarations.RegExLiteralExpressionDeclarationProto(); + regExLiteralExpression.setValue(value); + + let literalExpression = new declarations.LiteralExpressionDeclarationProto(); + literalExpression.setRegExliteral(regExLiteralExpression); + return this.asExpression(literalExpression); + } + private createFunctionDeclaration(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, uid: String): ProtoMessage { let functionDeclaration = new declarations.FunctionDeclarationProto(); diff --git a/typescript/ts-converter/src/ast/ast.ts b/typescript/ts-converter/src/ast/ast.ts index d02c7dbfa..f5431d7e2 100644 --- a/typescript/ts-converter/src/ast/ast.ts +++ b/typescript/ts-converter/src/ast/ast.ts @@ -114,9 +114,44 @@ export declare class PropertyDeclaration implements MemberDeclaration { serializeBinary(): Int8Array; } -export declare class Expression implements Declaration { - kind: TypeDeclaration; - meta: String; +export declare class IdentifierExpression implements Expression { + identifier: IdentifierEntity; + serializeBinary(): Int8Array; +} + +export declare class BinaryExpression implements Expression { + left: Expression; + operator: string; + right: Expression; + serializeBinary(): Int8Array; +} + +export declare class NumericLiteralExpression implements LiteralExpression { + value: string; + serializeBinary(): Int8Array; +} + +export declare class BigIntLiteralExpression implements LiteralExpression { + value: string; + serializeBinary(): Int8Array; +} + +export declare class StringLiteralExpression implements LiteralExpression { + value: string; + serializeBinary(): Int8Array; +} + +export declare class RegExLiteralExpression implements LiteralExpression { + value: string; + serializeBinary(): Int8Array; +} + +export declare interface LiteralExpression extends Expression {} + +export declare interface Expression extends Declaration {} + +export declare class ExpressionStatement implements Declaration { + expression: Expression; serializeBinary(): Int8Array; } diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index f3c44048a..b15f813a5 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -167,9 +167,51 @@ message ReferenceEntityProto { string uid = 1; } +message StringLiteralExpressionDeclarationProto { + string value = 1; +} + +message NumericLiteralExpressionDeclarationProto { + string value = 1; +} + +message BigIntLiteralExpressionDeclarationProto { + string value = 1; +} + +message RegExLiteralExpressionDeclarationProto { + string value = 1; +} + +message LiteralExpressionDeclarationProto { + oneof type { + StringLiteralExpressionDeclarationProto stringLiteral = 1; + NumericLiteralExpressionDeclarationProto numericLiteral = 2; + BigIntLiteralExpressionDeclarationProto bigIntLiteral = 3; + RegExLiteralExpressionDeclarationProto regExLiteral = 4; + } +} + +message IdentifierExpressionDeclarationProto { + IdentifierEntityProto identifier = 1; +} + +message BinaryExpressionDeclarationProto { + ExpressionDeclarationProto left = 1; + string operator = 2; + ExpressionDeclarationProto right = 3; +} + message ExpressionDeclarationProto { - TypeDeclarationProto kind = 1; - string meta = 2; + oneof type { + IdentifierExpressionDeclarationProto identifierExpression = 1; + BinaryExpressionDeclarationProto binaryExpression = 2; + LiteralExpressionDeclarationProto literalExpression = 3; + } +} + +message ExpressionStatementDeclarationProto { + ExpressionDeclarationProto expression = 1; } message ParameterDeclarationProto { @@ -237,6 +279,7 @@ message TopLevelEntityProto { ModuleDeclarationProto moduleDeclaration = 7; ExportAssignmentDeclarationProto exportAssignment = 8; ImportEqualsDeclarationProto importEquals = 9; + ExpressionStatementDeclarationProto expressionStatement = 10; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ExpressionDeclaration.kt index 4a17c5905..5514c113a 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ExpressionDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ExpressionDeclaration.kt @@ -1,10 +1,5 @@ package org.jetbrains.dukat.tsmodel import org.jetbrains.dukat.astCommon.Entity -import org.jetbrains.dukat.tsmodel.types.TypeDeclaration - -data class ExpressionDeclaration( - val kind: TypeDeclaration, - val meta: String? -) : Entity \ No newline at end of file +interface ExpressionDeclaration : Entity \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ExpressionStatementDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ExpressionStatementDeclaration.kt new file mode 100644 index 000000000..33ade529c --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ExpressionStatementDeclaration.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.tsmodel + +data class ExpressionStatementDeclaration( + val expression: ExpressionDeclaration +) : TopLevelDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/BinaryExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/BinaryExpressionDeclaration.kt new file mode 100644 index 000000000..d425f7985 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/BinaryExpressionDeclaration.kt @@ -0,0 +1,9 @@ +package org.jetbrains.dukat.tsmodel.expression + +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +data class BinaryExpressionDeclaration( + val left: ExpressionDeclaration, + val operator: String, + val right: ExpressionDeclaration +) : ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/IdentifierExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/IdentifierExpressionDeclaration.kt new file mode 100644 index 000000000..ed36a4da3 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/IdentifierExpressionDeclaration.kt @@ -0,0 +1,8 @@ +package org.jetbrains.dukat.tsmodel.expression + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +data class IdentifierExpressionDeclaration( + val identifier: IdentifierEntity +) : ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/BigIntLiteralExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/BigIntLiteralExpressionDeclaration.kt new file mode 100644 index 000000000..9907309f0 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/BigIntLiteralExpressionDeclaration.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.tsmodel.expression.literal + +data class BigIntLiteralExpressionDeclaration( + val value: String +) : LiteralExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/LiteralExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/LiteralExpressionDeclaration.kt new file mode 100644 index 000000000..8f6e3e309 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/LiteralExpressionDeclaration.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.tsmodel.expression.literal + +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +interface LiteralExpressionDeclaration : ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/NumericLiteralExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/NumericLiteralExpressionDeclaration.kt new file mode 100644 index 000000000..35e474af5 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/NumericLiteralExpressionDeclaration.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.tsmodel.expression.literal + +data class NumericLiteralExpressionDeclaration( + val value: String +) : LiteralExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/RegExLiteralExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/RegExLiteralExpressionDeclaration.kt new file mode 100644 index 000000000..d8de1b06d --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/RegExLiteralExpressionDeclaration.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.tsmodel.expression.literal + +data class RegExLiteralExpressionDeclaration( + val value: String +) : LiteralExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/StringLiteralExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/StringLiteralExpressionDeclaration.kt new file mode 100644 index 000000000..8b71a00b8 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/StringLiteralExpressionDeclaration.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.tsmodel.expression.literal + +data class StringLiteralExpressionDeclaration( + val value: String +) : LiteralExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 3fea6ffc6..f545e9915 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -15,6 +15,7 @@ import org.jetbrains.dukat.tsmodel.EnumDeclaration import org.jetbrains.dukat.tsmodel.EnumTokenDeclaration import org.jetbrains.dukat.tsmodel.ExportAssignmentDeclaration import org.jetbrains.dukat.tsmodel.ExpressionDeclaration +import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.GeneratedInterfaceReferenceDeclaration import org.jetbrains.dukat.tsmodel.HeritageClauseDeclaration @@ -33,6 +34,13 @@ import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.TypeAliasDeclaration import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration +import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.RegExLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration import org.jetbrains.dukat.tsmodel.types.IndexSignatureDeclaration import org.jetbrains.dukat.tsmodel.types.IntersectionTypeDeclaration @@ -156,6 +164,10 @@ fun Declarations.ImportEqualsDeclarationProto.convert(): ImportEqualsDeclaration return ImportEqualsDeclaration(name, moduleReference.convert(), uid) } +fun Declarations.ExpressionStatementDeclarationProto.convert(): ExpressionStatementDeclaration { + return ExpressionStatementDeclaration(expression.convert()) +} + fun Declarations.TopLevelEntityProto.convert(): TopLevelDeclaration { return when { hasClassDeclaration() -> classDeclaration.convert() @@ -167,6 +179,7 @@ fun Declarations.TopLevelEntityProto.convert(): TopLevelDeclaration { hasModuleDeclaration() -> moduleDeclaration.convert() hasExportAssignment() -> exportAssignment.convert() hasImportEquals() -> importEquals.convert() + hasExpressionStatement() -> expressionStatement.convert() else -> throw Exception("unknown TopLevelEntity: ${this}") } } @@ -261,7 +274,7 @@ private fun Declarations.ParameterDeclarationProto.convert(): ParameterDeclarati name, type.convert(), if (hasInitializer()) { - ExpressionDeclaration(initializer.kind.convert(), initializer.meta) + initializer.convert() } else null, vararg, optional @@ -299,6 +312,44 @@ private fun Declarations.ParameterValueDeclarationProto.convert(): ParameterValu } } +fun Declarations.NumericLiteralExpressionDeclarationProto.convert() = NumericLiteralExpressionDeclaration(value) +fun Declarations.BigIntLiteralExpressionDeclarationProto.convert() = BigIntLiteralExpressionDeclaration(value) +fun Declarations.StringLiteralExpressionDeclarationProto.convert() = StringLiteralExpressionDeclaration(value) +fun Declarations.RegExLiteralExpressionDeclarationProto.convert() = RegExLiteralExpressionDeclaration(value) + +fun Declarations.LiteralExpressionDeclarationProto.convert() : LiteralExpressionDeclaration { + return when { + hasNumericLiteral() -> numericLiteral.convert() + hasBigIntLiteral() -> bigIntLiteral.convert() + hasStringLiteral() -> stringLiteral.convert() + hasRegExLiteral() -> regExLiteral.convert() + else -> throw Exception("unknown literalExpression: ${this}") + } +} + +fun Declarations.BinaryExpressionDeclarationProto.convert() : BinaryExpressionDeclaration { + return BinaryExpressionDeclaration( + left = left.convert(), + operator = operator, + right = right.convert() + ) +} + +fun Declarations.IdentifierExpressionDeclarationProto.convert() : IdentifierExpressionDeclaration { + return IdentifierExpressionDeclaration( + identifier = identifier.convert() + ) +} + +fun Declarations.ExpressionDeclarationProto.convert() : ExpressionDeclaration { + return when { + hasBinaryExpression() -> binaryExpression.convert() + hasIdentifierExpression() -> identifierExpression.convert() + hasLiteralExpression() -> literalExpression.convert() + else -> throw Exception("unknown expression: ${this}") + } +} + fun Declarations.SourceFileDeclarationProto.convert(): SourceFileDeclaration { return SourceFileDeclaration( fileName, diff --git a/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt b/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt index f7beaa6c3..c6b6b2688 100644 --- a/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt +++ b/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt @@ -44,7 +44,6 @@ import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.ConstructorDeclaration import org.jetbrains.dukat.tsmodel.DefinitionInfoDeclaration import org.jetbrains.dukat.tsmodel.EnumDeclaration -import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.GeneratedInterfaceDeclaration import org.jetbrains.dukat.tsmodel.HeritageClauseDeclaration @@ -60,11 +59,11 @@ import org.jetbrains.dukat.tsmodel.SourceSetDeclaration import org.jetbrains.dukat.tsmodel.TypeAliasDeclaration import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration +import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.types.IndexSignatureDeclaration import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration import org.jetbrains.dukat.tsmodel.types.TypeDeclaration import org.jetbrains.dukat.tsmodel.types.canBeJson -import org.jetbrains.dukat.tsmodel.types.isSimpleType import java.io.File import org.jetbrains.dukat.ast.model.nodes.DocumentRootNode as DocumentRootNode1 @@ -400,8 +399,11 @@ private class LowerDeclarationsToNodes(private val fileName: String, private val FunctionNode( QualifierEntity(name, IdentifierEntity("invoke")), convertParameters(declaration.parameters.map { param -> - val initializer = if (param.initializer?.kind?.isSimpleType("definedExternally") == true) { - ExpressionDeclaration(TypeDeclaration(IdentifierEntity("null"), emptyList()), null) + val initializer = if ( + param.initializer is IdentifierExpressionDeclaration && + (param.initializer as IdentifierExpressionDeclaration).identifier.value == "definedExternally" + ) { + IdentifierExpressionDeclaration(IdentifierEntity("null")) } else { param.initializer } diff --git a/typescript/ts-node-lowering/src/org/jetrbains/dukat/nodeLowering/lowerings/rearrangeGeneratedEntities.kt b/typescript/ts-node-lowering/src/org/jetrbains/dukat/nodeLowering/lowerings/rearrangeGeneratedEntities.kt index 20b5033f1..cc2901322 100644 --- a/typescript/ts-node-lowering/src/org/jetrbains/dukat/nodeLowering/lowerings/rearrangeGeneratedEntities.kt +++ b/typescript/ts-node-lowering/src/org/jetrbains/dukat/nodeLowering/lowerings/rearrangeGeneratedEntities.kt @@ -15,6 +15,7 @@ import org.jetbrains.dukat.astCommon.NameEntity import org.jetbrains.dukat.astCommon.TopLevelEntity import org.jetbrains.dukat.ownerContext.NodeOwner import org.jetbrains.dukat.panic.raiseConcern +import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration import org.jetbrains.dukat.tsmodel.GeneratedInterfaceReferenceDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration import org.jetrbains.dukat.nodeLowering.NodeWithOwnerTypeLowering @@ -30,6 +31,7 @@ private fun Entity.getKey(): String { is TypeAliasNode -> uid is EnumNode -> "" is DocumentRootNode -> "" + is ExpressionStatementDeclaration -> "" else -> raiseConcern("unknown TopLevelNode ${this}") { "" } } } From e8302c9bd02d496f5a08ce4e08cbf481c990fa25 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Oct 2019 11:44:31 +0100 Subject: [PATCH 002/172] Gather function blocks to proto. Fix property initializers in tests --- compiler/test/data/typescript/a/function.d.kt | 18 +++++++++ compiler/test/data/typescript/a/function.d.ts | 11 ++++++ typescript/ts-converter/src/AstConverter.ts | 37 +++++++++++++++---- typescript/ts-converter/src/ast/AstFactory.ts | 32 +++++++++++++--- typescript/ts-converter/src/ast/ast.ts | 5 +++ .../ts-model-proto/src/Declarations.proto | 12 +++++- .../dukat/nodeIntroduction/introduceNodes.kt | 2 +- 7 files changed, 101 insertions(+), 16 deletions(-) create mode 100644 compiler/test/data/typescript/a/function.d.kt create mode 100644 compiler/test/data/typescript/a/function.d.ts diff --git a/compiler/test/data/typescript/a/function.d.kt b/compiler/test/data/typescript/a/function.d.kt new file mode 100644 index 000000000..9eccd17a2 --- /dev/null +++ b/compiler/test/data/typescript/a/function.d.kt @@ -0,0 +1,18 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun foo(a: Any, b: Any) \ No newline at end of file diff --git a/compiler/test/data/typescript/a/function.d.ts b/compiler/test/data/typescript/a/function.d.ts new file mode 100644 index 000000000..06f31d3fd --- /dev/null +++ b/compiler/test/data/typescript/a/function.d.ts @@ -0,0 +1,11 @@ +var x = 1337 + +x = 42 + +export function foo(a, b) { + return a - b +} + +function nonExport() { + return "not gonna get exported!!!" +} \ No newline at end of file diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index 7fc874f30..b06978e2a 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -5,6 +5,7 @@ import {createLogger} from "./Logger"; import {uid} from "./uid"; import {createExportContent} from "./ExportContent"; import { + Block, ClassDeclaration, Declaration, DefinitionInfoDeclaration, @@ -190,12 +191,26 @@ export class AstConverter { return typeParameterDeclarations; } + convertBlock(block: ts.Block): Block | null { + if(block) { + const statements: Declaration[] = []; + + for (let statement of block.statements) { + for (let decl of this.convertTopLevelStatement(statement)) { + this.registerDeclaration(decl, statements) + } + } + + return this.astFactory.createBlockDeclaration(statements); + } else { + return null; + } + } + convertFunctionDeclaration(functionDeclaration: ts.FunctionDeclaration): FunctionDeclaration | null { let typeParameterDeclarations: Array = this.convertTypeParams(functionDeclaration.typeParameters); - functionDeclaration.body - let parameterDeclarations = functionDeclaration.parameters .map( (param, count) => this.convertParameterDeclaration(param, count) @@ -217,6 +232,7 @@ export class AstConverter { returnType, typeParameterDeclarations, this.convertModifiers(functionDeclaration.modifiers), + this.convertBlock(functionDeclaration.body), uid ); } @@ -285,7 +301,8 @@ export class AstConverter { declaration.type ? this.convertType(declaration.type) : this.createTypeDeclaration("Unit"), typeParameterDeclarations, - this.convertModifiers(declaration.modifiers) + this.convertModifiers(declaration.modifiers), + this.convertBlock(declaration.body), ); } @@ -293,9 +310,9 @@ export class AstConverter { } - createMethodDeclaration(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array): FunctionDeclaration { + createMethodDeclaration(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, body: Block | null): FunctionDeclaration { // TODO: reintroduce method declaration - return this.astFactory.createFunctionDeclarationAsMember(name, parameters, type, typeParams, modifiers, "__NO_UID__"); + return this.astFactory.createFunctionDeclarationAsMember(name, parameters, type, typeParams, modifiers, body, "__NO_UID__"); } private createTypeDeclaration(value: string, params: Array = [], typeReference: string | null = null): TypeDeclaration { @@ -524,13 +541,13 @@ export class AstConverter { convertParameterDeclaration(param: ts.ParameterDeclaration, index: number): ParameterDeclaration { let initializer: Expression | null = null; if (param.initializer != null) { - // TODO: this never happens in tests and I should add one + // TODO: move this logic to kotlin initializer = this.createIdentifierExpression( - "definedExternally", + "definedExternally /* " + param.initializer.getText() + " */", ) } else if (param.questionToken != null) { initializer = this.createIdentifierExpression( - "definedExternally", + "definedExternally /* null */", ) } @@ -880,6 +897,10 @@ export class AstConverter { res.push(this.astFactory.createExpressionStatement( this.convertExpression(statement.expression) )); + } else if (ts.isReturnStatement(statement)) { + res.push(this.astFactory.createReturnStatement( + this.convertExpression(statement.expression) + )); } else if (ts.isTypeAliasDeclaration(statement)) { if (ts.isTypeLiteralNode(statement.type)) { res.push(this.convertTypeLiteralToInterfaceDeclaration( diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index 2fa16340d..981a3051b 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -1,6 +1,6 @@ import * as declarations from "declarations"; import { - BinaryExpression, + BinaryExpression, Block, CallSignatureDeclaration, ClassDeclaration, ClassLikeDeclaration, @@ -128,6 +128,17 @@ export class AstFactory implements AstFactory { return topLevelEntity; } + createReturnStatement(expression: Expression): ExpressionStatement { + let returnStatement = new declarations.ReturnStatementDeclarationProto(); + if(expression != null) { + returnStatement.setExpression(expression); + } + + let topLevelEntity = new declarations.TopLevelEntityProto(); + topLevelEntity.setExpressionstatement(returnStatement); + return topLevelEntity; + } + createIdentifierExpressionDeclarationAsExpression(identifier: IdentifierEntity): IdentifierExpression { let identifierExpressionProto = new declarations.IdentifierExpressionDeclarationProto(); identifierExpressionProto.setIdentifier(identifier); @@ -191,27 +202,36 @@ export class AstFactory implements AstFactory { } - private createFunctionDeclaration(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, uid: String): ProtoMessage { + createBlockDeclaration(statements: Array): Block { + let block = new declarations.BlockDeclarationProto(); + block.setStatementsList(statements); + return block + } + + private createFunctionDeclaration(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, body: Block | null, uid: String): ProtoMessage { let functionDeclaration = new declarations.FunctionDeclarationProto(); functionDeclaration.setName(name); functionDeclaration.setParametersList(parameters); functionDeclaration.setType(type); functionDeclaration.setTypeparametersList(typeParams); functionDeclaration.setModifiersList(modifiers); + if(body) { + functionDeclaration.setBody(body); + } functionDeclaration.setUid(uid); return functionDeclaration } - createFunctionDeclarationAsMember(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, uid: String): FunctionDeclaration { - let functionDeclaration = this.createFunctionDeclaration(name, parameters, type, typeParams, modifiers, uid); + createFunctionDeclarationAsMember(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, body: Block | null, uid: String): FunctionDeclaration { + let functionDeclaration = this.createFunctionDeclaration(name, parameters, type, typeParams, modifiers, body, uid); let memberProto = new declarations.MemberEntityProto(); memberProto.setFunctiondeclaration(functionDeclaration); return memberProto; } - createFunctionDeclarationAsTopLevel(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, uid: String): FunctionDeclaration { - let functionDeclaration = this.createFunctionDeclaration(name, parameters, type, typeParams, modifiers, uid); + createFunctionDeclarationAsTopLevel(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, body: Block | null, uid: String): FunctionDeclaration { + let functionDeclaration = this.createFunctionDeclaration(name, parameters, type, typeParams, modifiers, body, uid); let topLevelEntity = new declarations.TopLevelEntityProto(); topLevelEntity.setFunctiondeclaration(functionDeclaration); diff --git a/typescript/ts-converter/src/ast/ast.ts b/typescript/ts-converter/src/ast/ast.ts index f5431d7e2..a0197d9f5 100644 --- a/typescript/ts-converter/src/ast/ast.ts +++ b/typescript/ts-converter/src/ast/ast.ts @@ -189,6 +189,11 @@ export declare class TypeDeclaration implements ParameterValue { serializeBinary(): Int8Array; } +export declare class Block implements Declaration { + statements: Array + serializeBinary(): Int8Array; +} + export declare class FunctionDeclaration implements MemberDeclaration { serializeBinary(): Int8Array; } diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index b15f813a5..98c7d4bd1 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -112,13 +112,18 @@ message ConstructorDeclarationProto { repeated ModifierDeclarationProto modifiers = 3; } +message BlockDeclarationProto { + repeated TopLevelEntityProto statements = 1; +} + message FunctionDeclarationProto { string name = 1; repeated ParameterDeclarationProto parameters = 2; ParameterValueDeclarationProto type = 3; repeated TypeParameterDeclarationProto typeParameters = 4; repeated ModifierDeclarationProto modifiers = 5; - string uid = 6; + BlockDeclarationProto body = 6; + string uid = 7; } message IndexSignatureDeclarationProto { @@ -214,6 +219,10 @@ message ExpressionStatementDeclarationProto { ExpressionDeclarationProto expression = 1; } +message ReturnStatementDeclarationProto { + ExpressionDeclarationProto expression = 1; +} + message ParameterDeclarationProto { string name = 1; ParameterValueDeclarationProto type = 2; @@ -280,6 +289,7 @@ message TopLevelEntityProto { ExportAssignmentDeclarationProto exportAssignment = 8; ImportEqualsDeclarationProto importEquals = 9; ExpressionStatementDeclarationProto expressionStatement = 10; + ReturnStatementDeclarationProto returnStatement = 11; } } diff --git a/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt b/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt index c6b6b2688..2c8679e9f 100644 --- a/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt +++ b/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt @@ -401,7 +401,7 @@ private class LowerDeclarationsToNodes(private val fileName: String, private val convertParameters(declaration.parameters.map { param -> val initializer = if ( param.initializer is IdentifierExpressionDeclaration && - (param.initializer as IdentifierExpressionDeclaration).identifier.value == "definedExternally" + (param.initializer as IdentifierExpressionDeclaration).identifier.value == "definedExternally /* null */" ) { IdentifierExpressionDeclaration(IdentifierEntity("null")) } else { From 76715d62b0d57b791533eed0363c3606dbc08c89 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Oct 2019 12:01:49 +0100 Subject: [PATCH 003/172] Convert function bodies to typescript model --- .../org/jetbrains/dukat/tsmodel/BlockDeclaration.kt | 5 +++++ .../org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt | 1 + .../jetbrains/dukat/tsmodel/factory/convertProtobuf.kt | 10 ++++++++++ 3 files changed, 16 insertions(+) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt new file mode 100644 index 000000000..ddc3e0acc --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.tsmodel + +data class BlockDeclaration( + val statements: List +) : TopLevelDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt index 6b1705e31..ed6bc0921 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt @@ -9,5 +9,6 @@ data class FunctionDeclaration( val type: ParameterValueDeclaration, val typeParameters: List, val modifiers: List, + val body: BlockDeclaration?, override val uid: String ) : MemberEntity, TopLevelDeclaration, WithUidDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index f545e9915..bb1218247 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -7,6 +7,7 @@ import org.jetbrains.dukat.astCommon.MemberEntity import org.jetbrains.dukat.astCommon.NameEntity import org.jetbrains.dukat.astCommon.QualifierEntity import org.jetbrains.dukat.astCommon.ReferenceEntity +import org.jetbrains.dukat.tsmodel.BlockDeclaration import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.ConstructorDeclaration @@ -114,6 +115,12 @@ fun Declarations.InterfaceDeclarationProto.convert(): InterfaceDeclaration { ) } +fun Declarations.BlockDeclarationProto.convert() : BlockDeclaration { + return BlockDeclaration( + statements = statementsList.map { it.convert() } + ) +} + fun Declarations.FunctionDeclarationProto.convert(): FunctionDeclaration { return FunctionDeclaration( name, @@ -121,6 +128,9 @@ fun Declarations.FunctionDeclarationProto.convert(): FunctionDeclaration { type.convert(), typeParametersList.map { it.convert() }, modifiersList.map { it.convert() }, + if(hasBody()) { + body.convert() + } else null, uid ) } From 116e33de1b3d17366115cd568e44227171c8c930 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Oct 2019 12:11:18 +0100 Subject: [PATCH 004/172] Fix operator conversion to string --- typescript/ts-converter/src/AstConverter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index b06978e2a..81274a267 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -374,7 +374,7 @@ export class AstConverter { return this.createBinaryExpression( this.convertExpression(expression.left), - ts.tokenToString(expression.operatorToken), + ts.tokenToString(expression.operatorToken.kind), this.convertExpression(expression.right) ) } From e39ddf8318b91f0adbcf907ed86740a1a869edfb Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Oct 2019 14:22:01 +0100 Subject: [PATCH 005/172] Fix return statement conversion --- compiler/test/data/typescript/a/function.d.ts | 4 ++++ typescript/ts-converter/src/AstConverter.ts | 7 ++++++- typescript/ts-converter/src/ast/AstFactory.ts | 6 +++--- .../org/jetbrains/dukat/tsmodel/BlockDeclaration.kt | 6 ++++-- .../dukat/tsmodel/ReturnStatementDeclaration.kt | 5 +++++ .../jetbrains/dukat/tsmodel/factory/convertProtobuf.kt | 10 ++++++++++ 6 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ReturnStatementDeclaration.kt diff --git a/compiler/test/data/typescript/a/function.d.ts b/compiler/test/data/typescript/a/function.d.ts index 06f31d3fd..4b246a517 100644 --- a/compiler/test/data/typescript/a/function.d.ts +++ b/compiler/test/data/typescript/a/function.d.ts @@ -8,4 +8,8 @@ export function foo(a, b) { function nonExport() { return "not gonna get exported!!!" +} + +function undefined() { + return; } \ No newline at end of file diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index 81274a267..f87bd827d 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -898,8 +898,13 @@ export class AstConverter { this.convertExpression(statement.expression) )); } else if (ts.isReturnStatement(statement)) { + let expression : Expression | null = null; + if(statement.expression) { + expression = this.convertExpression(statement.expression) + } + res.push(this.astFactory.createReturnStatement( - this.convertExpression(statement.expression) + expression )); } else if (ts.isTypeAliasDeclaration(statement)) { if (ts.isTypeLiteralNode(statement.type)) { diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index 981a3051b..c2bd8d1e1 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -128,14 +128,14 @@ export class AstFactory implements AstFactory { return topLevelEntity; } - createReturnStatement(expression: Expression): ExpressionStatement { + createReturnStatement(expression: Expression | null): ExpressionStatement { let returnStatement = new declarations.ReturnStatementDeclarationProto(); - if(expression != null) { + if(expression) { returnStatement.setExpression(expression); } let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setExpressionstatement(returnStatement); + topLevelEntity.setReturnstatement(returnStatement); return topLevelEntity; } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt index ddc3e0acc..c7d6a7a08 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt @@ -1,5 +1,7 @@ package org.jetbrains.dukat.tsmodel +import org.jetbrains.dukat.astCommon.TopLevelEntity + data class BlockDeclaration( - val statements: List -) : TopLevelDeclaration \ No newline at end of file + val statements: List +) : TopLevelEntity \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ReturnStatementDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ReturnStatementDeclaration.kt new file mode 100644 index 000000000..ad7e2a888 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ReturnStatementDeclaration.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.tsmodel + +class ReturnStatementDeclaration( + val expression: ExpressionDeclaration? +) : TopLevelDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index bb1218247..cdf9ddfec 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -27,6 +27,7 @@ import org.jetbrains.dukat.tsmodel.ModifierDeclaration import org.jetbrains.dukat.tsmodel.ModuleDeclaration import org.jetbrains.dukat.tsmodel.ParameterDeclaration import org.jetbrains.dukat.tsmodel.PropertyDeclaration +import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration import org.jetbrains.dukat.tsmodel.SourceBundleDeclaration import org.jetbrains.dukat.tsmodel.SourceFileDeclaration import org.jetbrains.dukat.tsmodel.SourceSetDeclaration @@ -178,6 +179,14 @@ fun Declarations.ExpressionStatementDeclarationProto.convert(): ExpressionStatem return ExpressionStatementDeclaration(expression.convert()) } +fun Declarations.ReturnStatementDeclarationProto.convert(): ReturnStatementDeclaration { + return ReturnStatementDeclaration( + if(hasExpression()) { + expression.convert() + } else null + ) +} + fun Declarations.TopLevelEntityProto.convert(): TopLevelDeclaration { return when { hasClassDeclaration() -> classDeclaration.convert() @@ -190,6 +199,7 @@ fun Declarations.TopLevelEntityProto.convert(): TopLevelDeclaration { hasExportAssignment() -> exportAssignment.convert() hasImportEquals() -> importEquals.convert() hasExpressionStatement() -> expressionStatement.convert() + hasReturnStatement() -> returnStatement.convert() else -> throw Exception("unknown TopLevelEntity: ${this}") } } From 3dbfa4d73c0231fb8c66e34d7ca698da6f52e002 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Oct 2019 18:39:04 +0100 Subject: [PATCH 006/172] Add simple type analysis --- compiler/build.gradle | 1 + javascript/js-type-analysis/build.gradle | 9 ++ .../dukat/js/type_analysis/expression.kt | 49 +++++++++++ .../jetbrains/dukat/js/type_analysis/types.kt | 82 +++++++++++++++++++ settings.gradle | 3 + 5 files changed, 144 insertions(+) create mode 100644 javascript/js-type-analysis/build.gradle create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt diff --git a/compiler/build.gradle b/compiler/build.gradle index 5f4287056..b9e18c27e 100644 --- a/compiler/build.gradle +++ b/compiler/build.gradle @@ -50,6 +50,7 @@ dependencies { implementation(project(":idl-parser")) implementation(project(":idl-reference-resolver")) implementation(project(":itertools")) + implementation(project(":js-type-analysis")) implementation(project(":logging")) implementation(project(":model-lowerings")) implementation(project(":model-lowerings-common")) diff --git a/javascript/js-type-analysis/build.gradle b/javascript/js-type-analysis/build.gradle new file mode 100644 index 000000000..b092ebeb5 --- /dev/null +++ b/javascript/js-type-analysis/build.gradle @@ -0,0 +1,9 @@ +plugins { + id 'kotlin' +} + +dependencies { + implementation(project(":ast-common")) + implementation(project(":panic")) + implementation(project(":ts-model")) +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt new file mode 100644 index 000000000..9d26c34ae --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt @@ -0,0 +1,49 @@ +package org.jetbrains.dukat.js.type_analysis + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration +import org.jetbrains.dukat.tsmodel.types.TypeDeclaration + +fun constraintFromOperator(operator: String) : TypeDeclaration { + return when (operator) { + "-", "*", "/", "**", "%", "++", "--", "-=", "*=", "/=", "%=", "**=" -> TypeDeclaration( + value = IdentifierEntity("number"), + params = emptyList(), + nullable = false + ) + "==", "===", "!=", "!==", ">", "<", ">=", "<=", "&&", "||", "!" -> TypeDeclaration( + value = IdentifierEntity("boolean"), + params = emptyList(), + nullable = false + ) + else -> TypeDeclaration( + value = IdentifierEntity("Any"), + params = emptyList(), + nullable = true + ) + } +} + +fun BinaryExpressionDeclaration.calculateConstraint() : TypeDeclaration { + return when(operator) { + "=" -> right.calculateConstraint() + else -> constraintFromOperator(operator) + } +} + +fun ExpressionDeclaration?.calculateConstraint() : TypeDeclaration { + return when(this) { + is BinaryExpressionDeclaration -> this.calculateConstraint() + null -> TypeDeclaration( + value = IdentifierEntity("Unit"), + params = emptyList(), + nullable = false + ) + else -> TypeDeclaration( + value = IdentifierEntity("Any"), + params = emptyList(), + nullable = true + ) + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt new file mode 100644 index 000000000..91826ce6d --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt @@ -0,0 +1,82 @@ +package org.jetbrains.dukat.js.type_analysis + +import org.jetbrains.dukat.astCommon.MemberEntity +import org.jetbrains.dukat.astCommon.TopLevelEntity +import org.jetbrains.dukat.panic.raiseConcern +import org.jetbrains.dukat.tsmodel.BlockDeclaration +import org.jetbrains.dukat.tsmodel.ClassDeclaration +import org.jetbrains.dukat.tsmodel.ConstructorDeclaration +import org.jetbrains.dukat.tsmodel.EnumDeclaration +import org.jetbrains.dukat.tsmodel.ExportAssignmentDeclaration +import org.jetbrains.dukat.tsmodel.ModuleDeclaration +import org.jetbrains.dukat.tsmodel.SourceFileDeclaration +import org.jetbrains.dukat.tsmodel.SourceSetDeclaration +import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration +import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.ImportEqualsDeclaration +import org.jetbrains.dukat.tsmodel.InterfaceDeclaration +import org.jetbrains.dukat.tsmodel.PropertyDeclaration +import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration +import org.jetbrains.dukat.tsmodel.TypeAliasDeclaration +import org.jetbrains.dukat.tsmodel.VariableDeclaration +import org.jetbrains.dukat.tsmodel.types.IndexSignatureDeclaration + +fun FunctionDeclaration.introduceTypes() : FunctionDeclaration { + if(this.body != null) { + for(statement in this.body!!.statements) { + when(statement) { + is ReturnStatementDeclaration -> return copy(type = statement.expression.calculateConstraint()) + } + } + + return copy(type = null.calculateConstraint()) + } else { + return this; + } +} + +fun ConstructorDeclaration.introduceTypes() : ConstructorDeclaration { + return this +} + +fun MemberEntity.introduceTypes(): MemberEntity { + return when(this) { + is FunctionDeclaration -> this.introduceTypes() + is ConstructorDeclaration -> this.introduceTypes() + is PropertyDeclaration -> this + is IndexSignatureDeclaration -> this + else -> raiseConcern("Unexpected member entity type <${this.javaClass}>") { this } + } +} + +fun ClassDeclaration.introduceTypes() = copy(members = members.map { it.introduceTypes() }) + +fun BlockDeclaration.introduceTypes() = copy(statements = statements.map { it.introduceTypes() }) + +fun TopLevelEntity.introduceTypes(): TopLevelEntity { + return when(this) { + is FunctionDeclaration -> this.introduceTypes() + is ClassDeclaration -> this.introduceTypes() + is BlockDeclaration -> this.introduceTypes() + is ModuleDeclaration -> this.introduceTypes() + is InterfaceDeclaration -> this //TODO check if this needs modification + is VariableDeclaration, + is EnumDeclaration, + is ExportAssignmentDeclaration, + is ImportEqualsDeclaration, + is TypeAliasDeclaration, + is ReturnStatementDeclaration, + is ExpressionStatementDeclaration -> this + else -> raiseConcern("Unexpected top level entity type <${this.javaClass}>") { this } + } +} + +fun ModuleDeclaration.introduceTypes(): ModuleDeclaration = copy(declarations = declarations.map { it.introduceTypes() }) + +fun SourceFileDeclaration.introduceTypes(): SourceFileDeclaration { + return if (fileName.endsWith(".d.ts")) { //TODO replace with ".js" + copy(root = root.introduceTypes()) + } else this +} + +fun SourceSetDeclaration.introduceTypes() = copy(sources = sources.map{ it.introduceTypes() }) diff --git a/settings.gradle b/settings.gradle index 2ed3317c4..958783ea9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -53,6 +53,7 @@ include 'idl-parser' include 'idl-reference-resolver' include 'interop' include 'itertools' +include 'js-type-analysis' include 'logging' include 'model-lowerings' include 'module-name-resolver' @@ -76,6 +77,8 @@ project(':idl-models').projectDir = file("$rootDir/idl/idl-models") project(':idl-parser').projectDir = file("$rootDir/idl/idl-parser") project(':idl-reference-resolver').projectDir = file("$rootDir/idl/idl-reference-resolver") +project(':js-type-analysis').projectDir = file("$rootDir/javascript/js-type-analysis") + project(':ts-ast-declarations').projectDir = file("$rootDir/typescript/ts-ast-declarations") project(':ts-converter').projectDir = file("$rootDir/typescript/ts-converter") project(':ts-lowerings').projectDir = file("$rootDir/typescript/ts-lowerings") From d906f147ece982a3c8bd4a694cf4998986268bff Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Oct 2019 09:50:59 +0100 Subject: [PATCH 007/172] Delete javascript test --- compiler/test/data/typescript/a/function.d.kt | 18 ------------------ compiler/test/data/typescript/a/function.d.ts | 15 --------------- 2 files changed, 33 deletions(-) delete mode 100644 compiler/test/data/typescript/a/function.d.kt delete mode 100644 compiler/test/data/typescript/a/function.d.ts diff --git a/compiler/test/data/typescript/a/function.d.kt b/compiler/test/data/typescript/a/function.d.kt deleted file mode 100644 index 9eccd17a2..000000000 --- a/compiler/test/data/typescript/a/function.d.kt +++ /dev/null @@ -1,18 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") - -import kotlin.js.* -import kotlin.js.Json -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external fun foo(a: Any, b: Any) \ No newline at end of file diff --git a/compiler/test/data/typescript/a/function.d.ts b/compiler/test/data/typescript/a/function.d.ts deleted file mode 100644 index 4b246a517..000000000 --- a/compiler/test/data/typescript/a/function.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -var x = 1337 - -x = 42 - -export function foo(a, b) { - return a - b -} - -function nonExport() { - return "not gonna get exported!!!" -} - -function undefined() { - return; -} \ No newline at end of file From 025cb8e4b252263bb69387beac30368ebd416eb9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Oct 2019 10:00:38 +0100 Subject: [PATCH 008/172] Formatting --- typescript/ts-converter/src/AstConverter.ts | 16 ++++++++-------- typescript/ts-converter/src/ast/AstFactory.ts | 4 ++-- .../dukat/tsmodel/factory/convertProtobuf.kt | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index f87bd827d..301f3a71c 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -192,7 +192,7 @@ export class AstConverter { } convertBlock(block: ts.Block): Block | null { - if(block) { + if (block) { const statements: Declaration[] = []; for (let statement of block.statements) { @@ -396,17 +396,17 @@ export class AstConverter { } convertExpression(expression: ts.Expression): Expression { - if(ts.isBinaryExpression(expression)) { + if (ts.isBinaryExpression(expression)) { return this.convertBinaryExpression(expression); - } else if(ts.isIdentifier(expression)) { + } else if (ts.isIdentifier(expression)) { return this.convertIdentifierExpression(expression); - } else if(ts.isNumericLiteral(expression)) { + } else if (ts.isNumericLiteral(expression)) { return this.convertNumericLiteralExpression(expression); - } else if(ts.isBigIntLiteral(expression)) { + } else if (ts.isBigIntLiteral(expression)) { return this.convertBigIntLiteralExpression(expression); - } else if(ts.isStringLiteral(expression)) { + } else if (ts.isStringLiteral(expression)) { return this.convertStringLiteralExpression(expression); - } else if(ts.isRegularExpressionLiteral(expression)) { + } else if (ts.isRegularExpressionLiteral(expression)) { return this.convertRegExLiteralExpression(expression); } else { return this.createIdentifierExpression('/* ' + expression.getText() + ' */') @@ -899,7 +899,7 @@ export class AstConverter { )); } else if (ts.isReturnStatement(statement)) { let expression : Expression | null = null; - if(statement.expression) { + if (statement.expression) { expression = this.convertExpression(statement.expression) } diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index c2bd8d1e1..fbcb84649 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -130,7 +130,7 @@ export class AstFactory implements AstFactory { createReturnStatement(expression: Expression | null): ExpressionStatement { let returnStatement = new declarations.ReturnStatementDeclarationProto(); - if(expression) { + if (expression) { returnStatement.setExpression(expression); } @@ -215,7 +215,7 @@ export class AstFactory implements AstFactory { functionDeclaration.setType(type); functionDeclaration.setTypeparametersList(typeParams); functionDeclaration.setModifiersList(modifiers); - if(body) { + if (body) { functionDeclaration.setBody(body); } functionDeclaration.setUid(uid); diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index cdf9ddfec..bf5f818d6 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -129,7 +129,7 @@ fun Declarations.FunctionDeclarationProto.convert(): FunctionDeclaration { type.convert(), typeParametersList.map { it.convert() }, modifiersList.map { it.convert() }, - if(hasBody()) { + if (hasBody()) { body.convert() } else null, uid From 4b830f18876ecfe737cf613cbf5657d8798bf191 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Oct 2019 10:11:42 +0100 Subject: [PATCH 009/172] Formatting --- typescript/ts-converter/src/ast/AstFactory.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index fbcb84649..44957e684 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -1,6 +1,7 @@ import * as declarations from "declarations"; import { - BinaryExpression, Block, + BinaryExpression, + Block, CallSignatureDeclaration, ClassDeclaration, ClassLikeDeclaration, @@ -15,21 +16,24 @@ import { FunctionDeclaration, FunctionTypeDeclaration, HeritageClauseDeclaration, - IdentifierEntity, IdentifierExpression, + IdentifierEntity, + IdentifierExpression, ImportEqualsDeclaration, IndexSignatureDeclaration, InterfaceDeclaration, - IntersectionTypeDeclaration, LiteralExpression, + IntersectionTypeDeclaration, + LiteralExpression, MemberDeclaration, MethodSignatureDeclaration, ModifierDeclaration, ModuleDeclaration, ModuleReferenceDeclaration, - NameEntity, NumericLiteralExpression, + NameEntity, ObjectLiteral, ParameterDeclaration, ParameterValue, - PropertyDeclaration, ProtoMessage, + PropertyDeclaration, + ProtoMessage, QualifierEntity, ReferenceEntity, SourceFileDeclaration, From 96ee0fc056275050a3af1c60e3fbf916df81f464 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Oct 2019 13:17:45 +0100 Subject: [PATCH 010/172] Introduce constraints to define types in steps --- .../js/type_analysis/constraint/Constraint.kt | 7 +++ .../container/ConstraintContainer.kt | 18 ++++++++ .../container/ReturnConstraintContainer.kt | 27 ++++++++++++ .../resolved/BooleanTypeConstraint.kt | 5 +++ .../resolved/NumberTypeConstraint.kt | 5 +++ .../constraint/resolved/ResolvedConstraint.kt | 9 ++++ .../resolved/StringTypeConstraint.kt | 5 +++ .../constraint/resolved/UnitTypeConstraint.kt | 5 +++ .../dukat/js/type_analysis/expression.kt | 44 +++++-------------- .../jetbrains/dukat/js/type_analysis/types.kt | 9 +++- 10 files changed, 100 insertions(+), 34 deletions(-) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/Constraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BooleanTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NumberTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/StringTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/UnitTypeConstraint.kt diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/Constraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/Constraint.kt new file mode 100644 index 000000000..6088049f3 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/Constraint.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.js.type_analysis.constraint + +import org.jetbrains.dukat.js.type_analysis.constraint.resolved.ResolvedConstraint + +interface Constraint { + fun resolve(): ResolvedConstraint +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt new file mode 100644 index 000000000..2eca2942e --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt @@ -0,0 +1,18 @@ +package org.jetbrains.dukat.js.type_analysis.constraint.container + +import org.jetbrains.dukat.js.type_analysis.constraint.Constraint +import org.jetbrains.dukat.tsmodel.types.TypeDeclaration + +abstract class ConstraintContainer(protected val constraints: MutableSet = mutableSetOf()) { + operator fun plusAssign(constraint: Constraint) { + constraints += constraint + } + + operator fun plusAssign(newConstraints: Collection) { + constraints.addAll(newConstraints) + } + + abstract fun copy() : ConstraintContainer + + abstract fun resolveToType() : TypeDeclaration +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt new file mode 100644 index 000000000..ba5b35f5e --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt @@ -0,0 +1,27 @@ +package org.jetbrains.dukat.js.type_analysis.constraint.container + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.js.type_analysis.constraint.Constraint +import org.jetbrains.dukat.tsmodel.types.TypeDeclaration + +class ReturnConstraintContainer(constraints: MutableSet = mutableSetOf()) : ConstraintContainer(constraints) { + override fun copy(): ConstraintContainer { + return ReturnConstraintContainer(constraints) + } + + override fun resolveToType(): TypeDeclaration { + return if(constraints.isEmpty()) { + TypeDeclaration( + value = IdentifierEntity("Unit"), + params = emptyList(), + nullable = false + ) + } else { + TypeDeclaration( + value = IdentifierEntity("Any"), + params = emptyList(), + nullable = true + ) + } + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BooleanTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BooleanTypeConstraint.kt new file mode 100644 index 000000000..55b766c0e --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BooleanTypeConstraint.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.js.type_analysis.constraint.resolved + +object BooleanTypeConstraint : ResolvedConstraint { + override val typeName = "boolean" +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NumberTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NumberTypeConstraint.kt new file mode 100644 index 000000000..3b41a3cee --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NumberTypeConstraint.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.js.type_analysis.constraint.resolved + +object NumberTypeConstraint : ResolvedConstraint { + override val typeName = "number" +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt new file mode 100644 index 000000000..940caf446 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt @@ -0,0 +1,9 @@ +package org.jetbrains.dukat.js.type_analysis.constraint.resolved + +import org.jetbrains.dukat.js.type_analysis.constraint.Constraint + +interface ResolvedConstraint : Constraint { + override fun resolve() = this + + val typeName: String +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/StringTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/StringTypeConstraint.kt new file mode 100644 index 000000000..9648ba9b5 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/StringTypeConstraint.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.js.type_analysis.constraint.resolved + +object StringTypeConstraint : ResolvedConstraint { + override val typeName = "string" +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/UnitTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/UnitTypeConstraint.kt new file mode 100644 index 000000000..8fdb30a93 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/UnitTypeConstraint.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.js.type_analysis.constraint.resolved + +object UnitTypeConstraint : ResolvedConstraint { + override val typeName = "Unit" +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt index 9d26c34ae..ed5f16443 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt @@ -1,49 +1,29 @@ package org.jetbrains.dukat.js.type_analysis -import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.js.type_analysis.constraint.Constraint +import org.jetbrains.dukat.js.type_analysis.constraint.resolved.BooleanTypeConstraint +import org.jetbrains.dukat.js.type_analysis.constraint.resolved.NumberTypeConstraint import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration -import org.jetbrains.dukat.tsmodel.types.TypeDeclaration -fun constraintFromOperator(operator: String) : TypeDeclaration { +fun constraintFromOperator(operator: String) : Set { return when (operator) { - "-", "*", "/", "**", "%", "++", "--", "-=", "*=", "/=", "%=", "**=" -> TypeDeclaration( - value = IdentifierEntity("number"), - params = emptyList(), - nullable = false - ) - "==", "===", "!=", "!==", ">", "<", ">=", "<=", "&&", "||", "!" -> TypeDeclaration( - value = IdentifierEntity("boolean"), - params = emptyList(), - nullable = false - ) - else -> TypeDeclaration( - value = IdentifierEntity("Any"), - params = emptyList(), - nullable = true - ) + "-", "*", "/", "**", "%", "++", "--", "-=", "*=", "/=", "%=", "**=" -> setOf(NumberTypeConstraint) + "==", "===", "!=", "!==", ">", "<", ">=", "<=", "&&", "!" -> setOf(BooleanTypeConstraint) + else -> emptySet() } } -fun BinaryExpressionDeclaration.calculateConstraint() : TypeDeclaration { +fun BinaryExpressionDeclaration.calculateConstraints() : Set { return when(operator) { - "=" -> right.calculateConstraint() + "=" -> right.calculateConstraints() else -> constraintFromOperator(operator) } } -fun ExpressionDeclaration?.calculateConstraint() : TypeDeclaration { +fun ExpressionDeclaration?.calculateConstraints() : Set { return when(this) { - is BinaryExpressionDeclaration -> this.calculateConstraint() - null -> TypeDeclaration( - value = IdentifierEntity("Unit"), - params = emptyList(), - nullable = false - ) - else -> TypeDeclaration( - value = IdentifierEntity("Any"), - params = emptyList(), - nullable = true - ) + is BinaryExpressionDeclaration -> this.calculateConstraints() + else -> emptySet() } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt index 91826ce6d..f8dc7be1c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt @@ -2,6 +2,7 @@ package org.jetbrains.dukat.js.type_analysis import org.jetbrains.dukat.astCommon.MemberEntity import org.jetbrains.dukat.astCommon.TopLevelEntity +import org.jetbrains.dukat.js.type_analysis.constraint.container.ReturnConstraintContainer import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.BlockDeclaration import org.jetbrains.dukat.tsmodel.ClassDeclaration @@ -23,13 +24,17 @@ import org.jetbrains.dukat.tsmodel.types.IndexSignatureDeclaration fun FunctionDeclaration.introduceTypes() : FunctionDeclaration { if(this.body != null) { + val returnTypeConstraints = ReturnConstraintContainer() + for(statement in this.body!!.statements) { when(statement) { - is ReturnStatementDeclaration -> return copy(type = statement.expression.calculateConstraint()) + is ReturnStatementDeclaration -> returnTypeConstraints += statement.expression.calculateConstraints() } } - return copy(type = null.calculateConstraint()) + return copy( + type = returnTypeConstraints.resolveToType() + ) } else { return this; } From a01559d8727ee0dbf4cb798cdfe2d47efc63ffcc Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Oct 2019 13:20:32 +0100 Subject: [PATCH 011/172] Remove debug comments --- typescript/ts-converter/src/AstConverter.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index 301f3a71c..9c1566a9a 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -355,23 +355,12 @@ export class AstConverter { } convertIdentifierExpression(expression: ts.Expression): Expression { - /*console.log('Identifier:'); - console.log('\tEscaped text: ' + expression.escapedText); - console.log('\tUnescaped text: ' + expression.getText()); - console.log('\tOriginal keyword kind: ' + expression.originalKeywordKind); - console.log('\tIs in JSDoc namespace: ' + expression.isInJSDocNamespace);*/ - return this.createIdentifierExpression( expression.getText() ) } convertBinaryExpression(expression: ts.Expression): Expression { - /*console.log('Binary expression:'); - console.log('\tLeft:\n' + this.convertExpression(expression.left)); - console.log('\tOperator:\n' + ts.tokenToString(expression.operatorToken)); - console.log('\tRight:\n' + this.convertExpression(expression.right));*/ - return this.createBinaryExpression( this.convertExpression(expression.left), ts.tokenToString(expression.operatorToken.kind), From d694fdd1b56f06a7e1b1e9b132658fda4115d5ce Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Oct 2019 14:42:20 +0100 Subject: [PATCH 012/172] Correctly evaluate binary operator return types --- .../dukat/js/type_analysis/expression.kt | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt index ed5f16443..8b50f4144 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt @@ -6,18 +6,15 @@ import org.jetbrains.dukat.js.type_analysis.constraint.resolved.NumberTypeConstr import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration -fun constraintFromOperator(operator: String) : Set { - return when (operator) { - "-", "*", "/", "**", "%", "++", "--", "-=", "*=", "/=", "%=", "**=" -> setOf(NumberTypeConstraint) - "==", "===", "!=", "!==", ">", "<", ">=", "<=", "&&", "!" -> setOf(BooleanTypeConstraint) - else -> emptySet() - } -} - fun BinaryExpressionDeclaration.calculateConstraints() : Set { - return when(operator) { + return when (operator) { "=" -> right.calculateConstraints() - else -> constraintFromOperator(operator) + "-", "*", "/", "**", "%", "++", "--", "-=", "*=", "/=", "%=", "**=", //result and parameters must be numbers + "&", "|", "^", "<<", ">>" //result must be a number + -> setOf(NumberTypeConstraint) + "==", "===", "!=", "!==", ">", "<", ">=", "<=" //result must be a boolean + -> setOf(BooleanTypeConstraint) + else -> emptySet() } } From 0e0dd36a38f721391770410e9c7cc51a9bcc5f8e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Oct 2019 18:22:20 +0100 Subject: [PATCH 013/172] Add 'unknown' expression in TS AST, to allow access to source code text --- .../dukat/ast/model/nodes/ParameterNode.kt | 10 +++++--- typescript/ts-converter/src/AstConverter.ts | 23 +++++++++---------- typescript/ts-converter/src/ast/AstFactory.ts | 9 ++++++++ .../ts-model-proto/src/Declarations.proto | 5 ++++ .../UnknownExpressionDeclaration.kt | 8 +++++++ .../dukat/tsmodel/factory/convertProtobuf.kt | 8 +++++++ .../dukat/nodeIntroduction/introduceNodes.kt | 15 +++--------- 7 files changed, 51 insertions(+), 27 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/UnknownExpressionDeclaration.kt diff --git a/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/nodes/ParameterNode.kt b/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/nodes/ParameterNode.kt index 17791afd4..89bd7e274 100644 --- a/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/nodes/ParameterNode.kt +++ b/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/nodes/ParameterNode.kt @@ -1,8 +1,10 @@ package org.jetbrains.dukat.ast.model.nodes import org.jetbrains.dukat.astCommon.Entity +import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.tsmodel.ParameterDeclaration import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.UnknownExpressionDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration data class ParameterNode( @@ -19,10 +21,12 @@ data class ParameterNode( fun ParameterDeclaration.convertToNode(): ParameterNode = ParameterNode( name = name, type = type, - initializer = if (initializer != null && initializer is IdentifierExpressionDeclaration) { - TypeValueNode((initializer as IdentifierExpressionDeclaration).identifier, emptyList()) + initializer = if (initializer != null || optional) { + TypeValueNode(IdentifierEntity("definedExternally"), emptyList()) + } else null, + meta = if (initializer != null && initializer is UnknownExpressionDeclaration) { + (initializer as UnknownExpressionDeclaration).meta } else null, - meta = null, vararg = vararg, optional = optional ) \ No newline at end of file diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index 9c1566a9a..b148a09e9 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -354,10 +354,12 @@ export class AstConverter { return this.astFactory.createRegExLiteralDeclarationAsExpression(value); } + createUnknownExpression(value: string): Expression { + return this.astFactory.createUnknownExpressionDeclarationAsExpression(value); + } + convertIdentifierExpression(expression: ts.Expression): Expression { - return this.createIdentifierExpression( - expression.getText() - ) + return this.createIdentifierExpression(expression.getText()) } convertBinaryExpression(expression: ts.Expression): Expression { @@ -384,6 +386,10 @@ export class AstConverter { return this.createRegExLiteralExpression(expression.getText()) } + convertUnknownExpression(expression: ts.Expression): Expression { + return this.createUnknownExpression(expression.getText()) + } + convertExpression(expression: ts.Expression): Expression { if (ts.isBinaryExpression(expression)) { return this.convertBinaryExpression(expression); @@ -398,7 +404,7 @@ export class AstConverter { } else if (ts.isRegularExpressionLiteral(expression)) { return this.convertRegExLiteralExpression(expression); } else { - return this.createIdentifierExpression('/* ' + expression.getText() + ' */') + return this.convertUnknownExpression(expression) } } @@ -530,14 +536,7 @@ export class AstConverter { convertParameterDeclaration(param: ts.ParameterDeclaration, index: number): ParameterDeclaration { let initializer: Expression | null = null; if (param.initializer != null) { - // TODO: move this logic to kotlin - initializer = this.createIdentifierExpression( - "definedExternally /* " + param.initializer.getText() + " */", - ) - } else if (param.questionToken != null) { - initializer = this.createIdentifierExpression( - "definedExternally /* null */", - ) + initializer = this.convertUnknownExpression(param.initializer) } let paramType = this.convertType(param.type); diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index 44957e684..1b1ed7c6d 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -163,6 +163,15 @@ export class AstFactory implements AstFactory { return expression; } + createUnknownExpressionDeclarationAsExpression(meta: string): Expression { + let unknownExpression = new declarations.UnknownExpressionDeclarationProto(); + unknownExpression.setMeta(meta); + + let expression = new declarations.ExpressionDeclarationProto(); + expression.setUnknownexpression(unknownExpression); + return expression; + } + private asExpression(literalExpression: LiteralExpression): Expression { let expression = new declarations.ExpressionDeclarationProto(); expression.setLiteralexpression(literalExpression); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 98c7d4bd1..421b451bd 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -207,11 +207,16 @@ message BinaryExpressionDeclarationProto { ExpressionDeclarationProto right = 3; } +message UnknownExpressionDeclarationProto { + string meta = 1; +} + message ExpressionDeclarationProto { oneof type { IdentifierExpressionDeclarationProto identifierExpression = 1; BinaryExpressionDeclarationProto binaryExpression = 2; LiteralExpressionDeclarationProto literalExpression = 3; + UnknownExpressionDeclarationProto unknownExpression = 4; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/UnknownExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/UnknownExpressionDeclaration.kt new file mode 100644 index 000000000..ed6a29d82 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/UnknownExpressionDeclaration.kt @@ -0,0 +1,8 @@ +package org.jetbrains.dukat.tsmodel.expression + +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +//TODO convert all expressions, so that this is no longer necessary +data class UnknownExpressionDeclaration( + val meta: String +) : ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index bf5f818d6..178f28232 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -38,6 +38,7 @@ import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.UnknownExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDeclaration @@ -361,11 +362,18 @@ fun Declarations.IdentifierExpressionDeclarationProto.convert() : IdentifierExpr ) } +fun Declarations.UnknownExpressionDeclarationProto.convert() : UnknownExpressionDeclaration { + return UnknownExpressionDeclaration( + meta = meta + ) +} + fun Declarations.ExpressionDeclarationProto.convert() : ExpressionDeclaration { return when { hasBinaryExpression() -> binaryExpression.convert() hasIdentifierExpression() -> identifierExpression.convert() hasLiteralExpression() -> literalExpression.convert() + hasUnknownExpression() -> unknownExpression.convert() else -> throw Exception("unknown expression: ${this}") } } diff --git a/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt b/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt index 2c8679e9f..a87695f7a 100644 --- a/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt +++ b/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt @@ -44,6 +44,7 @@ import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.ConstructorDeclaration import org.jetbrains.dukat.tsmodel.DefinitionInfoDeclaration import org.jetbrains.dukat.tsmodel.EnumDeclaration +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.GeneratedInterfaceDeclaration import org.jetbrains.dukat.tsmodel.HeritageClauseDeclaration @@ -60,6 +61,7 @@ import org.jetbrains.dukat.tsmodel.TypeAliasDeclaration import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.UnknownExpressionDeclaration import org.jetbrains.dukat.tsmodel.types.IndexSignatureDeclaration import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration import org.jetbrains.dukat.tsmodel.types.TypeDeclaration @@ -398,18 +400,7 @@ private class LowerDeclarationsToNodes(private val fileName: String, private val is CallSignatureDeclaration -> listOf( FunctionNode( QualifierEntity(name, IdentifierEntity("invoke")), - convertParameters(declaration.parameters.map { param -> - val initializer = if ( - param.initializer is IdentifierExpressionDeclaration && - (param.initializer as IdentifierExpressionDeclaration).identifier.value == "definedExternally /* null */" - ) { - IdentifierExpressionDeclaration(IdentifierEntity("null")) - } else { - param.initializer - } - - param.copy(initializer = initializer) - }), + convertParameters(declaration.parameters), declaration.type, emptyList(), mutableListOf(), From f80708167bfb64321752f8410eedbcc788d8e4f1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Oct 2019 09:30:12 +0100 Subject: [PATCH 014/172] Remove wrongly implied 'null' in optional parameters (without explicit default values in TS) --- .../genericsWithObjectConstraint.d.kt | 2 +- .../class/inheritance/overrides.d.kt | 4 +- .../class/inheritance/withGeneric.d.kt | 2 +- .../class/override/withDefaultArgs.d.kt | 2 +- .../extendExternalDeclarations/simple.d.kt | 2 +- .../withGenericParams.d.kt | 2 +- .../generic/genericWithDefaultValue.d.kt | 4 +- .../interface/inheritance/withGeneric.d.kt | 2 +- .../moduleWith/firstLevelNamespace.d.kt | 2 +- .../moduleWith/function.d.kt | 2 +- .../functionAndSecondaryWithTrait.d.kt | 2 +- .../data/typescript/misc/missedOverloads.d.kt | 58 +++++++++---------- .../typescript/misc/stringTypeInAlias.d.kt | 8 +-- .../refToOuterVarAfterModule.d.kt | 2 +- .../functionsWithDefaultArguments.d.kt | 2 +- .../functionsWithOptionalFunctionType.d.kt | 2 +- .../functionsWithOptionalParameter.d.kt | 8 +-- .../unionType/withNullOrUndefined.d.kt | 2 +- .../typescript/utilityTypes/utilityTypes.d.kt | 2 +- 19 files changed, 55 insertions(+), 55 deletions(-) diff --git a/compiler/test/data/typescript/class/generics/genericsWithObjectConstraint.d.kt b/compiler/test/data/typescript/class/generics/genericsWithObjectConstraint.d.kt index c46a9b9ca..8fa3fa56a 100644 --- a/compiler/test/data/typescript/class/generics/genericsWithObjectConstraint.d.kt +++ b/compiler/test/data/typescript/class/generics/genericsWithObjectConstraint.d.kt @@ -25,7 +25,7 @@ external open class SomeClass { open fun ping(source: T) companion object { - fun foo(array: Array, classes: Array? = definedExternally /* null */): Array + fun foo(array: Array, classes: Array? = definedExternally): Array } } diff --git a/compiler/test/data/typescript/class/inheritance/overrides.d.kt b/compiler/test/data/typescript/class/inheritance/overrides.d.kt index 02ff15016..d075d51f2 100644 --- a/compiler/test/data/typescript/class/inheritance/overrides.d.kt +++ b/compiler/test/data/typescript/class/inheritance/overrides.d.kt @@ -23,9 +23,9 @@ external interface BaseEvent { var data: dynamic /* String | Number */ fun getDelegateTarget(): Shape fun getElement(): Element - fun transform(shape: T? = definedExternally /* null */): T + fun transform(shape: T? = definedExternally): T var prop: Any - fun queryByReturnType(query: String, parameters: Array? = definedExternally /* null */): Promise + fun queryByReturnType(query: String, parameters: Array? = definedExternally): Promise } external open class BoxStringEvent : BaseEvent { diff --git a/compiler/test/data/typescript/class/inheritance/withGeneric.d.kt b/compiler/test/data/typescript/class/inheritance/withGeneric.d.kt index 4cf28a640..751835fcf 100644 --- a/compiler/test/data/typescript/class/inheritance/withGeneric.d.kt +++ b/compiler/test/data/typescript/class/inheritance/withGeneric.d.kt @@ -17,5 +17,5 @@ import org.w3c.xhr.* external open class JQueryXHR : JQueryPromise, MyXMLHttpRequest { open fun overrideMimeType(mimeType: String): Any - open fun abort(statusText: String? = definedExternally /* null */) + open fun abort(statusText: String? = definedExternally) } diff --git a/compiler/test/data/typescript/class/override/withDefaultArgs.d.kt b/compiler/test/data/typescript/class/override/withDefaultArgs.d.kt index cbc7d8e09..5eb6b0b24 100644 --- a/compiler/test/data/typescript/class/override/withDefaultArgs.d.kt +++ b/compiler/test/data/typescript/class/override/withDefaultArgs.d.kt @@ -17,7 +17,7 @@ import org.w3c.xhr.* external open class Foo { open fun bar(a: Number = definedExternally /* 1 */) - open fun baz(a: Any? = definedExternally /* null */) + open fun baz(a: Any? = definedExternally) } external open class Boo : Foo { diff --git a/compiler/test/data/typescript/extendExternalDeclarations/simple.d.kt b/compiler/test/data/typescript/extendExternalDeclarations/simple.d.kt index d9a918b5d..caacb6b6a 100644 --- a/compiler/test/data/typescript/extendExternalDeclarations/simple.d.kt +++ b/compiler/test/data/typescript/extendExternalDeclarations/simple.d.kt @@ -27,4 +27,4 @@ inline var Event.someField: String get() = this.asDynamic().someField; set(value inline var Event.optionalField: Any? get() = this.asDynamic().optionalField; set(value) { this.asDynamic().optionalField = value } -inline operator fun Event.invoke(resourceId: String, hash: Any? = null, callback: Function<*>? = null) { this.asDynamic().invoke(resourceId, hash, callback) } +inline operator fun Event.invoke(resourceId: String, hash: Any? = definedExternally, callback: Function<*>? = definedExternally) { this.asDynamic().invoke(resourceId, hash, callback) } diff --git a/compiler/test/data/typescript/extendExternalDeclarations/withGenericParams.d.kt b/compiler/test/data/typescript/extendExternalDeclarations/withGenericParams.d.kt index 2e7cd771a..e73375ef0 100644 --- a/compiler/test/data/typescript/extendExternalDeclarations/withGenericParams.d.kt +++ b/compiler/test/data/typescript/extendExternalDeclarations/withGenericParams.d.kt @@ -53,5 +53,5 @@ external interface ArrayType { get() = definedExternally set(value) = definedExternally @nativeInvoke - operator fun invoke(resourceId: String, hash: Any? = definedExternally /* null */, callback: Function<*>? = definedExternally /* null */) + operator fun invoke(resourceId: String, hash: Any? = definedExternally, callback: Function<*>? = definedExternally) } diff --git a/compiler/test/data/typescript/generic/genericWithDefaultValue.d.kt b/compiler/test/data/typescript/generic/genericWithDefaultValue.d.kt index 5e412ee8a..a5c4b208f 100644 --- a/compiler/test/data/typescript/generic/genericWithDefaultValue.d.kt +++ b/compiler/test/data/typescript/generic/genericWithDefaultValue.d.kt @@ -22,7 +22,7 @@ external interface Chain { } external interface ChainOfArrays : Chain, Array> { - fun flatten(shallow: Boolean? = definedExternally /* null */): Chain + fun flatten(shallow: Boolean? = definedExternally): Chain } external interface AsyncResultObjectCallback { @@ -44,4 +44,4 @@ external interface `T$1` { operator fun set(key: String, value: R) } -external fun transform(arr: `T$0`, iteratee: (acc: `T$1`, item: T, key: String, callback: (error: E? /* = null */) -> Unit) -> Unit, callback: AsyncResultObjectCallback? = definedExternally /* null */) \ No newline at end of file +external fun transform(arr: `T$0`, iteratee: (acc: `T$1`, item: T, key: String, callback: (error: E? /* = null */) -> Unit) -> Unit, callback: AsyncResultObjectCallback? = definedExternally) \ No newline at end of file diff --git a/compiler/test/data/typescript/interface/inheritance/withGeneric.d.kt b/compiler/test/data/typescript/interface/inheritance/withGeneric.d.kt index caf0e543c..1b33ec5c8 100644 --- a/compiler/test/data/typescript/interface/inheritance/withGeneric.d.kt +++ b/compiler/test/data/typescript/interface/inheritance/withGeneric.d.kt @@ -17,7 +17,7 @@ import org.w3c.xhr.* external interface JQueryXHR : MyXMLHttpRequest, JQueryPromise { fun overrideMimeType(mimeType: String): Any - fun abort(statusText: String? = definedExternally /* null */) + fun abort(statusText: String? = definedExternally) } external interface Property diff --git a/compiler/test/data/typescript/mergeDeclarations/moduleWith/firstLevelNamespace.d.kt b/compiler/test/data/typescript/mergeDeclarations/moduleWith/firstLevelNamespace.d.kt index df02bbbc5..08232eadd 100644 --- a/compiler/test/data/typescript/mergeDeclarations/moduleWith/firstLevelNamespace.d.kt +++ b/compiler/test/data/typescript/mergeDeclarations/moduleWith/firstLevelNamespace.d.kt @@ -16,4 +16,4 @@ import org.w3c.workers.* import org.w3c.xhr.* @JsModule("") -external fun func(opts: String? = definedExternally /* null */): Number +external fun func(opts: String? = definedExternally): Number diff --git a/compiler/test/data/typescript/mergeDeclarations/moduleWith/function.d.kt b/compiler/test/data/typescript/mergeDeclarations/moduleWith/function.d.kt index 7fce0c958..dfbeca2fa 100644 --- a/compiler/test/data/typescript/mergeDeclarations/moduleWith/function.d.kt +++ b/compiler/test/data/typescript/mergeDeclarations/moduleWith/function.d.kt @@ -65,4 +65,4 @@ import org.w3c.xhr.* external var current: Fiber -external fun yield(value: Any? = definedExternally /* null */): Any +external fun yield(value: Any? = definedExternally): Any diff --git a/compiler/test/data/typescript/mergeDeclarations/moduleWith/functionAndSecondaryWithTrait.d.kt b/compiler/test/data/typescript/mergeDeclarations/moduleWith/functionAndSecondaryWithTrait.d.kt index 2f861fae9..eabd9b82e 100644 --- a/compiler/test/data/typescript/mergeDeclarations/moduleWith/functionAndSecondaryWithTrait.d.kt +++ b/compiler/test/data/typescript/mergeDeclarations/moduleWith/functionAndSecondaryWithTrait.d.kt @@ -65,4 +65,4 @@ import org.w3c.xhr.* external var current: Fiber -external fun yield(value: Any? = definedExternally /* null */): Any +external fun yield(value: Any? = definedExternally): Any diff --git a/compiler/test/data/typescript/misc/missedOverloads.d.kt b/compiler/test/data/typescript/misc/missedOverloads.d.kt index 7c1e2c409..af1f8cd27 100644 --- a/compiler/test/data/typescript/misc/missedOverloads.d.kt +++ b/compiler/test/data/typescript/misc/missedOverloads.d.kt @@ -24,68 +24,68 @@ external interface MyEvent external interface MyOptions external interface JQueryStatic { - fun get(url: String, success: (() -> Any)? = definedExternally /* null */, dataType: String? = definedExternally /* null */): MyXHR - fun get(url: String, data: Any? = definedExternally /* null */, success: (() -> Any)? = definedExternally /* null */, dataType: String? = definedExternally /* null */): MyXHR - fun get(url: String, data: String? = definedExternally /* null */, success: (() -> Any)? = definedExternally /* null */, dataType: String? = definedExternally /* null */): MyXHR + fun get(url: String, success: (() -> Any)? = definedExternally, dataType: String? = definedExternally): MyXHR + fun get(url: String, data: Any? = definedExternally, success: (() -> Any)? = definedExternally, dataType: String? = definedExternally): MyXHR + fun get(url: String, data: String? = definedExternally, success: (() -> Any)? = definedExternally, dataType: String? = definedExternally): MyXHR fun get(settings: MyOptions): MyXHR @nativeInvoke - operator fun invoke(selector: String, context: Element? = definedExternally /* null */): MyQuery + operator fun invoke(selector: String, context: Element? = definedExternally): MyQuery @nativeInvoke - operator fun invoke(selector: String, context: MyQuery? = definedExternally /* null */): MyQuery + operator fun invoke(selector: String, context: MyQuery? = definedExternally): MyQuery @nativeInvoke operator fun invoke(element: Element): MyQuery @nativeInvoke operator fun invoke(): MyQuery @nativeInvoke - operator fun invoke(html: String, ownerDocument: Document? = definedExternally /* null */): MyQuery + operator fun invoke(html: String, ownerDocument: Document? = definedExternally): MyQuery @nativeInvoke operator fun invoke(html: String, attributes: Any): MyQuery - fun fadeTo(duration: String, opacity: Number, complete: Function<*>? = definedExternally /* null */): MyQuery - fun fadeTo(duration: Number, opacity: Number, complete: Function<*>? = definedExternally /* null */): MyQuery - fun fadeTo(duration: String, opacity: Number, easing: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery - fun fadeTo(duration: Number, opacity: Number, easing: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery + fun fadeTo(duration: String, opacity: Number, complete: Function<*>? = definedExternally): MyQuery + fun fadeTo(duration: Number, opacity: Number, complete: Function<*>? = definedExternally): MyQuery + fun fadeTo(duration: String, opacity: Number, easing: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery + fun fadeTo(duration: Number, opacity: Number, easing: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery @nativeInvoke operator fun invoke(selector: String): MyQuery } external open class JJ { - open fun foo(data: String, context: HTMLElement? = definedExternally /* null */, keepScripts: Boolean? = definedExternally /* null */): Array - open fun hide(duration: Number? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery - open fun hide(duration: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery - open fun hide(duration: Number? = definedExternally /* null */, easing: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery - open fun hide(duration: String? = definedExternally /* null */, easing: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery + open fun foo(data: String, context: HTMLElement? = definedExternally, keepScripts: Boolean? = definedExternally): Array + open fun hide(duration: Number? = definedExternally, complete: Function<*>? = definedExternally): MyQuery + open fun hide(duration: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery + open fun hide(duration: Number? = definedExternally, easing: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery + open fun hide(duration: String? = definedExternally, easing: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery open fun hide(options: MyOptions): MyQuery - open fun trigger(eventType: String, extraParameters: Array? = definedExternally /* null */): MyQuery - open fun trigger(eventType: String, extraParameters: Any? = definedExternally /* null */): MyQuery - open fun trigger(event: MyEvent, extraParameters: Array? = definedExternally /* null */): MyQuery - open fun trigger(event: MyEvent, extraParameters: Any? = definedExternally /* null */): MyQuery + open fun trigger(eventType: String, extraParameters: Array? = definedExternally): MyQuery + open fun trigger(eventType: String, extraParameters: Any? = definedExternally): MyQuery + open fun trigger(event: MyEvent, extraParameters: Array? = definedExternally): MyQuery + open fun trigger(event: MyEvent, extraParameters: Any? = definedExternally): MyQuery open fun hide(): MyQuery open fun trigger(eventType: String): MyQuery open fun trigger(event: MyEvent): MyQuery } -external fun foo(data: String, context: HTMLElement? = definedExternally /* null */, keepScripts: Boolean? = definedExternally /* null */): Array +external fun foo(data: String, context: HTMLElement? = definedExternally, keepScripts: Boolean? = definedExternally): Array -external fun hide(duration: Number? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery +external fun hide(duration: Number? = definedExternally, complete: Function<*>? = definedExternally): MyQuery -external fun hide(duration: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery +external fun hide(duration: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery -external fun hide(duration: Number? = definedExternally /* null */, easing: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery +external fun hide(duration: Number? = definedExternally, easing: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery -external fun hide(duration: String? = definedExternally /* null */, easing: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery +external fun hide(duration: String? = definedExternally, easing: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery external fun hide(options: MyOptions): MyQuery -external fun trigger(eventType: String, extraParameters: Array? = definedExternally /* null */): MyQuery +external fun trigger(eventType: String, extraParameters: Array? = definedExternally): MyQuery -external fun trigger(eventType: String, extraParameters: Any? = definedExternally /* null */): MyQuery +external fun trigger(eventType: String, extraParameters: Any? = definedExternally): MyQuery -external fun trigger(event: MyEvent, extraParameters: Array? = definedExternally /* null */): MyQuery +external fun trigger(event: MyEvent, extraParameters: Array? = definedExternally): MyQuery -external fun trigger(event: MyEvent, extraParameters: Any? = definedExternally /* null */): MyQuery +external fun trigger(event: MyEvent, extraParameters: Any? = definedExternally): MyQuery external fun hide(): MyQuery external fun trigger(eventType: String): MyQuery -external fun trigger(event: MyEvent): MyQuery +external fun trigger(event: MyEvent): MyQuery \ No newline at end of file diff --git a/compiler/test/data/typescript/misc/stringTypeInAlias.d.kt b/compiler/test/data/typescript/misc/stringTypeInAlias.d.kt index e356a0b7f..0052d1730 100644 --- a/compiler/test/data/typescript/misc/stringTypeInAlias.d.kt +++ b/compiler/test/data/typescript/misc/stringTypeInAlias.d.kt @@ -21,10 +21,10 @@ external open class A11yDialog { constructor(el: Element?, containers: Element?) constructor(el: Element?, containers: String?) constructor(el: Element?, containers: Nothing?) - open fun create(el: Element? = definedExternally /* null */, containers: NodeList? = definedExternally /* null */) - open fun create(el: Element? = definedExternally /* null */, containers: Element? = definedExternally /* null */) - open fun create(el: Element? = definedExternally /* null */, containers: String? = definedExternally /* null */) - open fun create(el: Element? = definedExternally /* null */, containers: Nothing? = definedExternally /* null */) + open fun create(el: Element? = definedExternally, containers: NodeList? = definedExternally) + open fun create(el: Element? = definedExternally, containers: Element? = definedExternally) + open fun create(el: Element? = definedExternally, containers: String? = definedExternally) + open fun create(el: Element? = definedExternally, containers: Nothing? = definedExternally) open fun on(evt: String /* "show" */, callback: (dialogElement: Any, event: Event) -> Unit) open fun on(evt: String /* "hide" */, callback: (dialogElement: Any, event: Event) -> Unit) open fun on(evt: String /* "destroy" */, callback: (dialogElement: Any, event: Event) -> Unit) diff --git a/compiler/test/data/typescript/module/exportAssignment/refToOuterVarAfterModule.d.kt b/compiler/test/data/typescript/module/exportAssignment/refToOuterVarAfterModule.d.kt index 388f9ffe0..8eb843738 100644 --- a/compiler/test/data/typescript/module/exportAssignment/refToOuterVarAfterModule.d.kt +++ b/compiler/test/data/typescript/module/exportAssignment/refToOuterVarAfterModule.d.kt @@ -17,7 +17,7 @@ import org.w3c.xhr.* external interface JQueryStatic { fun ajax(settings: JQueryAjaxSettings): JQueryXHR - fun ajax(url: String, settings: JQueryAjaxSettings? = definedExternally /* null */): JQueryXHR + fun ajax(url: String, settings: JQueryAjaxSettings? = definedExternally): JQueryXHR } @JsModule("jquery") diff --git a/compiler/test/data/typescript/topLevelMembers/functions/functionsWithDefaultArguments.d.kt b/compiler/test/data/typescript/topLevelMembers/functions/functionsWithDefaultArguments.d.kt index 4649f1c87..0b6e3f681 100644 --- a/compiler/test/data/typescript/topLevelMembers/functions/functionsWithDefaultArguments.d.kt +++ b/compiler/test/data/typescript/topLevelMembers/functions/functionsWithDefaultArguments.d.kt @@ -19,4 +19,4 @@ external fun withOneAny(a: Any = definedExternally /* 0 */): Any external fun withOneString(s: String = definedExternally /* "foobar" */): String -external fun withOneStringAndOptional(s: String = definedExternally /* "something" */, settings: JQueryAjaxSettings? = definedExternally /* null */): Boolean +external fun withOneStringAndOptional(s: String = definedExternally /* "something" */, settings: JQueryAjaxSettings? = definedExternally): Boolean diff --git a/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalFunctionType.d.kt b/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalFunctionType.d.kt index 3068c0aeb..b5c9edcb6 100644 --- a/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalFunctionType.d.kt +++ b/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalFunctionType.d.kt @@ -15,4 +15,4 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun foo(f: ((a: Any) -> Boolean)? = definedExternally /* null */): Boolean +external fun foo(f: ((a: Any) -> Boolean)? = definedExternally): Boolean diff --git a/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalParameter.d.kt b/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalParameter.d.kt index ac291c9d6..a4b0203c8 100644 --- a/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalParameter.d.kt +++ b/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalParameter.d.kt @@ -15,10 +15,10 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun withOneAny(a: Any? = definedExternally /* null */): Any +external fun withOneAny(a: Any? = definedExternally): Any -external fun withOneString(s: String? = definedExternally /* null */): String +external fun withOneString(s: String? = definedExternally): String -external fun withManyArguments(s: String? = definedExternally /* null */, settings: JQueryAjaxSettings? = definedExternally /* null */): Boolean +external fun withManyArguments(s: String? = definedExternally, settings: JQueryAjaxSettings? = definedExternally): Boolean -external fun withOptionalQualified(opts: ping.Options? = definedExternally /* null */) +external fun withOptionalQualified(opts: ping.Options? = definedExternally) diff --git a/compiler/test/data/typescript/unionType/withNullOrUndefined.d.kt b/compiler/test/data/typescript/unionType/withNullOrUndefined.d.kt index 4fc9f1e93..93df104fb 100644 --- a/compiler/test/data/typescript/unionType/withNullOrUndefined.d.kt +++ b/compiler/test/data/typescript/unionType/withNullOrUndefined.d.kt @@ -21,7 +21,7 @@ external var bar: String? external fun bar(a: String?): Foo? -external fun baz(a: Foo?, b: Number? = definedExternally /* null */): Any? +external fun baz(a: Foo?, b: Number? = definedExternally): Any? external interface `T$0` { @nativeGetter diff --git a/compiler/test/data/typescript/utilityTypes/utilityTypes.d.kt b/compiler/test/data/typescript/utilityTypes/utilityTypes.d.kt index a06bba48a..1b9afd45f 100644 --- a/compiler/test/data/typescript/utilityTypes/utilityTypes.d.kt +++ b/compiler/test/data/typescript/utilityTypes/utilityTypes.d.kt @@ -25,6 +25,6 @@ external interface `T$0` { } @JsModule("") -external open class App(opts: `T$0` = definedExternally /* null */) { +external open class App(opts: `T$0` = definedExternally) { open fun pick(obj: T, keys: Array): Any } \ No newline at end of file From 811c71a7e5b0daa43333df376cd5be2335b05a0c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Oct 2019 09:30:12 +0100 Subject: [PATCH 015/172] Remove wrongly implied 'null' in optional parameters (without explicit default values in TS) in tests --- .../genericsWithObjectConstraint.d.kt | 2 +- .../class/inheritance/overrides.d.kt | 4 +- .../class/inheritance/withGeneric.d.kt | 2 +- .../class/override/withDefaultArgs.d.kt | 2 +- .../extendExternalDeclarations/simple.d.kt | 2 +- .../withGenericParams.d.kt | 2 +- .../generic/genericWithDefaultValue.d.kt | 4 +- .../interface/inheritance/withGeneric.d.kt | 2 +- .../moduleWith/firstLevelNamespace.d.kt | 2 +- .../moduleWith/function.d.kt | 2 +- .../functionAndSecondaryWithTrait.d.kt | 2 +- .../data/typescript/misc/missedOverloads.d.kt | 58 +++++++++---------- .../typescript/misc/stringTypeInAlias.d.kt | 8 +-- .../refToOuterVarAfterModule.d.kt | 2 +- .../functionsWithDefaultArguments.d.kt | 2 +- .../functionsWithOptionalFunctionType.d.kt | 2 +- .../functionsWithOptionalParameter.d.kt | 8 +-- .../unionType/withNullOrUndefined.d.kt | 2 +- .../typescript/utilityTypes/utilityTypes.d.kt | 2 +- 19 files changed, 55 insertions(+), 55 deletions(-) diff --git a/compiler/test/data/typescript/class/generics/genericsWithObjectConstraint.d.kt b/compiler/test/data/typescript/class/generics/genericsWithObjectConstraint.d.kt index c46a9b9ca..8fa3fa56a 100644 --- a/compiler/test/data/typescript/class/generics/genericsWithObjectConstraint.d.kt +++ b/compiler/test/data/typescript/class/generics/genericsWithObjectConstraint.d.kt @@ -25,7 +25,7 @@ external open class SomeClass { open fun ping(source: T) companion object { - fun foo(array: Array, classes: Array? = definedExternally /* null */): Array + fun foo(array: Array, classes: Array? = definedExternally): Array } } diff --git a/compiler/test/data/typescript/class/inheritance/overrides.d.kt b/compiler/test/data/typescript/class/inheritance/overrides.d.kt index 02ff15016..d075d51f2 100644 --- a/compiler/test/data/typescript/class/inheritance/overrides.d.kt +++ b/compiler/test/data/typescript/class/inheritance/overrides.d.kt @@ -23,9 +23,9 @@ external interface BaseEvent { var data: dynamic /* String | Number */ fun getDelegateTarget(): Shape fun getElement(): Element - fun transform(shape: T? = definedExternally /* null */): T + fun transform(shape: T? = definedExternally): T var prop: Any - fun queryByReturnType(query: String, parameters: Array? = definedExternally /* null */): Promise + fun queryByReturnType(query: String, parameters: Array? = definedExternally): Promise } external open class BoxStringEvent : BaseEvent { diff --git a/compiler/test/data/typescript/class/inheritance/withGeneric.d.kt b/compiler/test/data/typescript/class/inheritance/withGeneric.d.kt index 4cf28a640..751835fcf 100644 --- a/compiler/test/data/typescript/class/inheritance/withGeneric.d.kt +++ b/compiler/test/data/typescript/class/inheritance/withGeneric.d.kt @@ -17,5 +17,5 @@ import org.w3c.xhr.* external open class JQueryXHR : JQueryPromise, MyXMLHttpRequest { open fun overrideMimeType(mimeType: String): Any - open fun abort(statusText: String? = definedExternally /* null */) + open fun abort(statusText: String? = definedExternally) } diff --git a/compiler/test/data/typescript/class/override/withDefaultArgs.d.kt b/compiler/test/data/typescript/class/override/withDefaultArgs.d.kt index cbc7d8e09..5eb6b0b24 100644 --- a/compiler/test/data/typescript/class/override/withDefaultArgs.d.kt +++ b/compiler/test/data/typescript/class/override/withDefaultArgs.d.kt @@ -17,7 +17,7 @@ import org.w3c.xhr.* external open class Foo { open fun bar(a: Number = definedExternally /* 1 */) - open fun baz(a: Any? = definedExternally /* null */) + open fun baz(a: Any? = definedExternally) } external open class Boo : Foo { diff --git a/compiler/test/data/typescript/extendExternalDeclarations/simple.d.kt b/compiler/test/data/typescript/extendExternalDeclarations/simple.d.kt index d9a918b5d..caacb6b6a 100644 --- a/compiler/test/data/typescript/extendExternalDeclarations/simple.d.kt +++ b/compiler/test/data/typescript/extendExternalDeclarations/simple.d.kt @@ -27,4 +27,4 @@ inline var Event.someField: String get() = this.asDynamic().someField; set(value inline var Event.optionalField: Any? get() = this.asDynamic().optionalField; set(value) { this.asDynamic().optionalField = value } -inline operator fun Event.invoke(resourceId: String, hash: Any? = null, callback: Function<*>? = null) { this.asDynamic().invoke(resourceId, hash, callback) } +inline operator fun Event.invoke(resourceId: String, hash: Any? = definedExternally, callback: Function<*>? = definedExternally) { this.asDynamic().invoke(resourceId, hash, callback) } diff --git a/compiler/test/data/typescript/extendExternalDeclarations/withGenericParams.d.kt b/compiler/test/data/typescript/extendExternalDeclarations/withGenericParams.d.kt index 2e7cd771a..e73375ef0 100644 --- a/compiler/test/data/typescript/extendExternalDeclarations/withGenericParams.d.kt +++ b/compiler/test/data/typescript/extendExternalDeclarations/withGenericParams.d.kt @@ -53,5 +53,5 @@ external interface ArrayType { get() = definedExternally set(value) = definedExternally @nativeInvoke - operator fun invoke(resourceId: String, hash: Any? = definedExternally /* null */, callback: Function<*>? = definedExternally /* null */) + operator fun invoke(resourceId: String, hash: Any? = definedExternally, callback: Function<*>? = definedExternally) } diff --git a/compiler/test/data/typescript/generic/genericWithDefaultValue.d.kt b/compiler/test/data/typescript/generic/genericWithDefaultValue.d.kt index 5e412ee8a..a5c4b208f 100644 --- a/compiler/test/data/typescript/generic/genericWithDefaultValue.d.kt +++ b/compiler/test/data/typescript/generic/genericWithDefaultValue.d.kt @@ -22,7 +22,7 @@ external interface Chain { } external interface ChainOfArrays : Chain, Array> { - fun flatten(shallow: Boolean? = definedExternally /* null */): Chain + fun flatten(shallow: Boolean? = definedExternally): Chain } external interface AsyncResultObjectCallback { @@ -44,4 +44,4 @@ external interface `T$1` { operator fun set(key: String, value: R) } -external fun transform(arr: `T$0`, iteratee: (acc: `T$1`, item: T, key: String, callback: (error: E? /* = null */) -> Unit) -> Unit, callback: AsyncResultObjectCallback? = definedExternally /* null */) \ No newline at end of file +external fun transform(arr: `T$0`, iteratee: (acc: `T$1`, item: T, key: String, callback: (error: E? /* = null */) -> Unit) -> Unit, callback: AsyncResultObjectCallback? = definedExternally) \ No newline at end of file diff --git a/compiler/test/data/typescript/interface/inheritance/withGeneric.d.kt b/compiler/test/data/typescript/interface/inheritance/withGeneric.d.kt index caf0e543c..1b33ec5c8 100644 --- a/compiler/test/data/typescript/interface/inheritance/withGeneric.d.kt +++ b/compiler/test/data/typescript/interface/inheritance/withGeneric.d.kt @@ -17,7 +17,7 @@ import org.w3c.xhr.* external interface JQueryXHR : MyXMLHttpRequest, JQueryPromise { fun overrideMimeType(mimeType: String): Any - fun abort(statusText: String? = definedExternally /* null */) + fun abort(statusText: String? = definedExternally) } external interface Property diff --git a/compiler/test/data/typescript/mergeDeclarations/moduleWith/firstLevelNamespace.d.kt b/compiler/test/data/typescript/mergeDeclarations/moduleWith/firstLevelNamespace.d.kt index df02bbbc5..08232eadd 100644 --- a/compiler/test/data/typescript/mergeDeclarations/moduleWith/firstLevelNamespace.d.kt +++ b/compiler/test/data/typescript/mergeDeclarations/moduleWith/firstLevelNamespace.d.kt @@ -16,4 +16,4 @@ import org.w3c.workers.* import org.w3c.xhr.* @JsModule("") -external fun func(opts: String? = definedExternally /* null */): Number +external fun func(opts: String? = definedExternally): Number diff --git a/compiler/test/data/typescript/mergeDeclarations/moduleWith/function.d.kt b/compiler/test/data/typescript/mergeDeclarations/moduleWith/function.d.kt index 7fce0c958..dfbeca2fa 100644 --- a/compiler/test/data/typescript/mergeDeclarations/moduleWith/function.d.kt +++ b/compiler/test/data/typescript/mergeDeclarations/moduleWith/function.d.kt @@ -65,4 +65,4 @@ import org.w3c.xhr.* external var current: Fiber -external fun yield(value: Any? = definedExternally /* null */): Any +external fun yield(value: Any? = definedExternally): Any diff --git a/compiler/test/data/typescript/mergeDeclarations/moduleWith/functionAndSecondaryWithTrait.d.kt b/compiler/test/data/typescript/mergeDeclarations/moduleWith/functionAndSecondaryWithTrait.d.kt index 2f861fae9..eabd9b82e 100644 --- a/compiler/test/data/typescript/mergeDeclarations/moduleWith/functionAndSecondaryWithTrait.d.kt +++ b/compiler/test/data/typescript/mergeDeclarations/moduleWith/functionAndSecondaryWithTrait.d.kt @@ -65,4 +65,4 @@ import org.w3c.xhr.* external var current: Fiber -external fun yield(value: Any? = definedExternally /* null */): Any +external fun yield(value: Any? = definedExternally): Any diff --git a/compiler/test/data/typescript/misc/missedOverloads.d.kt b/compiler/test/data/typescript/misc/missedOverloads.d.kt index 7c1e2c409..af1f8cd27 100644 --- a/compiler/test/data/typescript/misc/missedOverloads.d.kt +++ b/compiler/test/data/typescript/misc/missedOverloads.d.kt @@ -24,68 +24,68 @@ external interface MyEvent external interface MyOptions external interface JQueryStatic { - fun get(url: String, success: (() -> Any)? = definedExternally /* null */, dataType: String? = definedExternally /* null */): MyXHR - fun get(url: String, data: Any? = definedExternally /* null */, success: (() -> Any)? = definedExternally /* null */, dataType: String? = definedExternally /* null */): MyXHR - fun get(url: String, data: String? = definedExternally /* null */, success: (() -> Any)? = definedExternally /* null */, dataType: String? = definedExternally /* null */): MyXHR + fun get(url: String, success: (() -> Any)? = definedExternally, dataType: String? = definedExternally): MyXHR + fun get(url: String, data: Any? = definedExternally, success: (() -> Any)? = definedExternally, dataType: String? = definedExternally): MyXHR + fun get(url: String, data: String? = definedExternally, success: (() -> Any)? = definedExternally, dataType: String? = definedExternally): MyXHR fun get(settings: MyOptions): MyXHR @nativeInvoke - operator fun invoke(selector: String, context: Element? = definedExternally /* null */): MyQuery + operator fun invoke(selector: String, context: Element? = definedExternally): MyQuery @nativeInvoke - operator fun invoke(selector: String, context: MyQuery? = definedExternally /* null */): MyQuery + operator fun invoke(selector: String, context: MyQuery? = definedExternally): MyQuery @nativeInvoke operator fun invoke(element: Element): MyQuery @nativeInvoke operator fun invoke(): MyQuery @nativeInvoke - operator fun invoke(html: String, ownerDocument: Document? = definedExternally /* null */): MyQuery + operator fun invoke(html: String, ownerDocument: Document? = definedExternally): MyQuery @nativeInvoke operator fun invoke(html: String, attributes: Any): MyQuery - fun fadeTo(duration: String, opacity: Number, complete: Function<*>? = definedExternally /* null */): MyQuery - fun fadeTo(duration: Number, opacity: Number, complete: Function<*>? = definedExternally /* null */): MyQuery - fun fadeTo(duration: String, opacity: Number, easing: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery - fun fadeTo(duration: Number, opacity: Number, easing: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery + fun fadeTo(duration: String, opacity: Number, complete: Function<*>? = definedExternally): MyQuery + fun fadeTo(duration: Number, opacity: Number, complete: Function<*>? = definedExternally): MyQuery + fun fadeTo(duration: String, opacity: Number, easing: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery + fun fadeTo(duration: Number, opacity: Number, easing: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery @nativeInvoke operator fun invoke(selector: String): MyQuery } external open class JJ { - open fun foo(data: String, context: HTMLElement? = definedExternally /* null */, keepScripts: Boolean? = definedExternally /* null */): Array - open fun hide(duration: Number? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery - open fun hide(duration: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery - open fun hide(duration: Number? = definedExternally /* null */, easing: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery - open fun hide(duration: String? = definedExternally /* null */, easing: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery + open fun foo(data: String, context: HTMLElement? = definedExternally, keepScripts: Boolean? = definedExternally): Array + open fun hide(duration: Number? = definedExternally, complete: Function<*>? = definedExternally): MyQuery + open fun hide(duration: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery + open fun hide(duration: Number? = definedExternally, easing: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery + open fun hide(duration: String? = definedExternally, easing: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery open fun hide(options: MyOptions): MyQuery - open fun trigger(eventType: String, extraParameters: Array? = definedExternally /* null */): MyQuery - open fun trigger(eventType: String, extraParameters: Any? = definedExternally /* null */): MyQuery - open fun trigger(event: MyEvent, extraParameters: Array? = definedExternally /* null */): MyQuery - open fun trigger(event: MyEvent, extraParameters: Any? = definedExternally /* null */): MyQuery + open fun trigger(eventType: String, extraParameters: Array? = definedExternally): MyQuery + open fun trigger(eventType: String, extraParameters: Any? = definedExternally): MyQuery + open fun trigger(event: MyEvent, extraParameters: Array? = definedExternally): MyQuery + open fun trigger(event: MyEvent, extraParameters: Any? = definedExternally): MyQuery open fun hide(): MyQuery open fun trigger(eventType: String): MyQuery open fun trigger(event: MyEvent): MyQuery } -external fun foo(data: String, context: HTMLElement? = definedExternally /* null */, keepScripts: Boolean? = definedExternally /* null */): Array +external fun foo(data: String, context: HTMLElement? = definedExternally, keepScripts: Boolean? = definedExternally): Array -external fun hide(duration: Number? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery +external fun hide(duration: Number? = definedExternally, complete: Function<*>? = definedExternally): MyQuery -external fun hide(duration: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery +external fun hide(duration: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery -external fun hide(duration: Number? = definedExternally /* null */, easing: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery +external fun hide(duration: Number? = definedExternally, easing: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery -external fun hide(duration: String? = definedExternally /* null */, easing: String? = definedExternally /* null */, complete: Function<*>? = definedExternally /* null */): MyQuery +external fun hide(duration: String? = definedExternally, easing: String? = definedExternally, complete: Function<*>? = definedExternally): MyQuery external fun hide(options: MyOptions): MyQuery -external fun trigger(eventType: String, extraParameters: Array? = definedExternally /* null */): MyQuery +external fun trigger(eventType: String, extraParameters: Array? = definedExternally): MyQuery -external fun trigger(eventType: String, extraParameters: Any? = definedExternally /* null */): MyQuery +external fun trigger(eventType: String, extraParameters: Any? = definedExternally): MyQuery -external fun trigger(event: MyEvent, extraParameters: Array? = definedExternally /* null */): MyQuery +external fun trigger(event: MyEvent, extraParameters: Array? = definedExternally): MyQuery -external fun trigger(event: MyEvent, extraParameters: Any? = definedExternally /* null */): MyQuery +external fun trigger(event: MyEvent, extraParameters: Any? = definedExternally): MyQuery external fun hide(): MyQuery external fun trigger(eventType: String): MyQuery -external fun trigger(event: MyEvent): MyQuery +external fun trigger(event: MyEvent): MyQuery \ No newline at end of file diff --git a/compiler/test/data/typescript/misc/stringTypeInAlias.d.kt b/compiler/test/data/typescript/misc/stringTypeInAlias.d.kt index e356a0b7f..0052d1730 100644 --- a/compiler/test/data/typescript/misc/stringTypeInAlias.d.kt +++ b/compiler/test/data/typescript/misc/stringTypeInAlias.d.kt @@ -21,10 +21,10 @@ external open class A11yDialog { constructor(el: Element?, containers: Element?) constructor(el: Element?, containers: String?) constructor(el: Element?, containers: Nothing?) - open fun create(el: Element? = definedExternally /* null */, containers: NodeList? = definedExternally /* null */) - open fun create(el: Element? = definedExternally /* null */, containers: Element? = definedExternally /* null */) - open fun create(el: Element? = definedExternally /* null */, containers: String? = definedExternally /* null */) - open fun create(el: Element? = definedExternally /* null */, containers: Nothing? = definedExternally /* null */) + open fun create(el: Element? = definedExternally, containers: NodeList? = definedExternally) + open fun create(el: Element? = definedExternally, containers: Element? = definedExternally) + open fun create(el: Element? = definedExternally, containers: String? = definedExternally) + open fun create(el: Element? = definedExternally, containers: Nothing? = definedExternally) open fun on(evt: String /* "show" */, callback: (dialogElement: Any, event: Event) -> Unit) open fun on(evt: String /* "hide" */, callback: (dialogElement: Any, event: Event) -> Unit) open fun on(evt: String /* "destroy" */, callback: (dialogElement: Any, event: Event) -> Unit) diff --git a/compiler/test/data/typescript/module/exportAssignment/refToOuterVarAfterModule.d.kt b/compiler/test/data/typescript/module/exportAssignment/refToOuterVarAfterModule.d.kt index 388f9ffe0..8eb843738 100644 --- a/compiler/test/data/typescript/module/exportAssignment/refToOuterVarAfterModule.d.kt +++ b/compiler/test/data/typescript/module/exportAssignment/refToOuterVarAfterModule.d.kt @@ -17,7 +17,7 @@ import org.w3c.xhr.* external interface JQueryStatic { fun ajax(settings: JQueryAjaxSettings): JQueryXHR - fun ajax(url: String, settings: JQueryAjaxSettings? = definedExternally /* null */): JQueryXHR + fun ajax(url: String, settings: JQueryAjaxSettings? = definedExternally): JQueryXHR } @JsModule("jquery") diff --git a/compiler/test/data/typescript/topLevelMembers/functions/functionsWithDefaultArguments.d.kt b/compiler/test/data/typescript/topLevelMembers/functions/functionsWithDefaultArguments.d.kt index 4649f1c87..0b6e3f681 100644 --- a/compiler/test/data/typescript/topLevelMembers/functions/functionsWithDefaultArguments.d.kt +++ b/compiler/test/data/typescript/topLevelMembers/functions/functionsWithDefaultArguments.d.kt @@ -19,4 +19,4 @@ external fun withOneAny(a: Any = definedExternally /* 0 */): Any external fun withOneString(s: String = definedExternally /* "foobar" */): String -external fun withOneStringAndOptional(s: String = definedExternally /* "something" */, settings: JQueryAjaxSettings? = definedExternally /* null */): Boolean +external fun withOneStringAndOptional(s: String = definedExternally /* "something" */, settings: JQueryAjaxSettings? = definedExternally): Boolean diff --git a/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalFunctionType.d.kt b/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalFunctionType.d.kt index 3068c0aeb..b5c9edcb6 100644 --- a/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalFunctionType.d.kt +++ b/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalFunctionType.d.kt @@ -15,4 +15,4 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun foo(f: ((a: Any) -> Boolean)? = definedExternally /* null */): Boolean +external fun foo(f: ((a: Any) -> Boolean)? = definedExternally): Boolean diff --git a/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalParameter.d.kt b/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalParameter.d.kt index ac291c9d6..a4b0203c8 100644 --- a/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalParameter.d.kt +++ b/compiler/test/data/typescript/topLevelMembers/functions/functionsWithOptionalParameter.d.kt @@ -15,10 +15,10 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun withOneAny(a: Any? = definedExternally /* null */): Any +external fun withOneAny(a: Any? = definedExternally): Any -external fun withOneString(s: String? = definedExternally /* null */): String +external fun withOneString(s: String? = definedExternally): String -external fun withManyArguments(s: String? = definedExternally /* null */, settings: JQueryAjaxSettings? = definedExternally /* null */): Boolean +external fun withManyArguments(s: String? = definedExternally, settings: JQueryAjaxSettings? = definedExternally): Boolean -external fun withOptionalQualified(opts: ping.Options? = definedExternally /* null */) +external fun withOptionalQualified(opts: ping.Options? = definedExternally) diff --git a/compiler/test/data/typescript/unionType/withNullOrUndefined.d.kt b/compiler/test/data/typescript/unionType/withNullOrUndefined.d.kt index 4fc9f1e93..93df104fb 100644 --- a/compiler/test/data/typescript/unionType/withNullOrUndefined.d.kt +++ b/compiler/test/data/typescript/unionType/withNullOrUndefined.d.kt @@ -21,7 +21,7 @@ external var bar: String? external fun bar(a: String?): Foo? -external fun baz(a: Foo?, b: Number? = definedExternally /* null */): Any? +external fun baz(a: Foo?, b: Number? = definedExternally): Any? external interface `T$0` { @nativeGetter diff --git a/compiler/test/data/typescript/utilityTypes/utilityTypes.d.kt b/compiler/test/data/typescript/utilityTypes/utilityTypes.d.kt index a06bba48a..1b9afd45f 100644 --- a/compiler/test/data/typescript/utilityTypes/utilityTypes.d.kt +++ b/compiler/test/data/typescript/utilityTypes/utilityTypes.d.kt @@ -25,6 +25,6 @@ external interface `T$0` { } @JsModule("") -external open class App(opts: `T$0` = definedExternally /* null */) { +external open class App(opts: `T$0` = definedExternally) { open fun pick(obj: T, keys: Array): Any } \ No newline at end of file From 8b1d082afd5d034e72bca98ee5cbbe006ee6fa26 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Oct 2019 11:49:18 +0100 Subject: [PATCH 016/172] Move expression conversion to seperate classes from 'AstConverter' and 'AstFactory' --- typescript/ts-converter/src/AstConverter.ts | 88 +------------------ .../src/ast/AstExpressionConverter.ts | 83 +++++++++++++++++ .../src/ast/AstExpressionFactory.ts | 81 +++++++++++++++++ typescript/ts-converter/src/ast/AstFactory.ts | 75 ---------------- typescript/ts-converter/src/ast/ast.ts | 32 ------- 5 files changed, 168 insertions(+), 191 deletions(-) create mode 100644 typescript/ts-converter/src/ast/AstExpressionConverter.ts create mode 100644 typescript/ts-converter/src/ast/AstExpressionFactory.ts diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index b148a09e9..02a5218c0 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -34,6 +34,7 @@ import { } from "./ast/ast"; import {AstFactory} from "./ast/AstFactory"; import {DeclarationResolver} from "./DeclarationResolver"; +import {AstExpressionConverter} from "./ast/AstExpressionConverter"; export class AstConverter { private exportContext = createExportContent(); @@ -328,87 +329,6 @@ export class AstConverter { } - createIdentifierExpression(name: string): Expression { - return this.astFactory.createIdentifierExpressionDeclarationAsExpression( - this.astFactory.createIdentifierDeclaration(name) - ); - } - - createBinaryExpression(left: Expression, operator: string, right: Expression): Expression { - return this.astFactory.createBinaryExpressionDeclarationAsExpression(left, operator, right); - } - - createNumericLiteralExpression(value: string): Expression { - return this.astFactory.createNumericLiteralDeclarationAsExpression(value); - } - - createBigIntLiteralExpression(value: string): Expression { - return this.astFactory.createBigIntLiteralDeclarationAsExpression(value); - } - - createStringLiteralExpression(value: string): Expression { - return this.astFactory.createStringLiteralDeclarationAsExpression(value); - } - - createRegExLiteralExpression(value: string): Expression { - return this.astFactory.createRegExLiteralDeclarationAsExpression(value); - } - - createUnknownExpression(value: string): Expression { - return this.astFactory.createUnknownExpressionDeclarationAsExpression(value); - } - - convertIdentifierExpression(expression: ts.Expression): Expression { - return this.createIdentifierExpression(expression.getText()) - } - - convertBinaryExpression(expression: ts.Expression): Expression { - return this.createBinaryExpression( - this.convertExpression(expression.left), - ts.tokenToString(expression.operatorToken.kind), - this.convertExpression(expression.right) - ) - } - - convertNumericLiteralExpression(expression: ts.Expression): Expression { - return this.createNumericLiteralExpression(expression.getText()) - } - - convertBigIntLiteralExpression(expression: ts.Expression): Expression { - return this.createBigIntLiteralExpression(expression.getText()) - } - - convertStringLiteralExpression(expression: ts.Expression): Expression { - return this.createStringLiteralExpression(expression.getText()) - } - - convertRegExLiteralExpression(expression: ts.Expression): Expression { - return this.createRegExLiteralExpression(expression.getText()) - } - - convertUnknownExpression(expression: ts.Expression): Expression { - return this.createUnknownExpression(expression.getText()) - } - - convertExpression(expression: ts.Expression): Expression { - if (ts.isBinaryExpression(expression)) { - return this.convertBinaryExpression(expression); - } else if (ts.isIdentifier(expression)) { - return this.convertIdentifierExpression(expression); - } else if (ts.isNumericLiteral(expression)) { - return this.convertNumericLiteralExpression(expression); - } else if (ts.isBigIntLiteral(expression)) { - return this.convertBigIntLiteralExpression(expression); - } else if (ts.isStringLiteral(expression)) { - return this.convertStringLiteralExpression(expression); - } else if (ts.isRegularExpressionLiteral(expression)) { - return this.convertRegExLiteralExpression(expression); - } else { - return this.convertUnknownExpression(expression) - } - } - - createIntersectionType(params: Array) { return this.astFactory.createIntersectionTypeDeclaration(params); } @@ -536,7 +456,7 @@ export class AstConverter { convertParameterDeclaration(param: ts.ParameterDeclaration, index: number): ParameterDeclaration { let initializer: Expression | null = null; if (param.initializer != null) { - initializer = this.convertUnknownExpression(param.initializer) + initializer = AstExpressionConverter.convertUnknownExpression(param.initializer) } let paramType = this.convertType(param.type); @@ -883,12 +803,12 @@ export class AstConverter { } } else if (ts.isExpressionStatement(statement)) { res.push(this.astFactory.createExpressionStatement( - this.convertExpression(statement.expression) + AstExpressionConverter.convertExpression(statement.expression) )); } else if (ts.isReturnStatement(statement)) { let expression : Expression | null = null; if (statement.expression) { - expression = this.convertExpression(statement.expression) + expression = AstExpressionConverter.convertExpression(statement.expression) } res.push(this.astFactory.createReturnStatement( diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts new file mode 100644 index 000000000..b5557474b --- /dev/null +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -0,0 +1,83 @@ +import * as ts from "typescript-services-api"; +import {Expression} from "./ast"; +import {AstExpressionFactory} from "./AstExpressionFactory"; + +export class AstExpressionConverter { + static createIdentifierExpression(name: string): Expression { + return AstExpressionFactory.createIdentifierExpressionDeclarationAsExpression(name); + } + + static createBinaryExpression(left: Expression, operator: string, right: Expression): Expression { + return AstExpressionFactory.createBinaryExpressionDeclarationAsExpression(left, operator, right); + } + + static createNumericLiteralExpression(value: string): Expression { + return AstExpressionFactory.createNumericLiteralDeclarationAsExpression(value); + } + + static createBigIntLiteralExpression(value: string): Expression { + return AstExpressionFactory.createBigIntLiteralDeclarationAsExpression(value); + } + + static createStringLiteralExpression(value: string): Expression { + return AstExpressionFactory.createStringLiteralDeclarationAsExpression(value); + } + + static createRegExLiteralExpression(value: string): Expression { + return AstExpressionFactory.createRegExLiteralDeclarationAsExpression(value); + } + + static createUnknownExpression(value: string): Expression { + return AstExpressionFactory.createUnknownExpressionDeclarationAsExpression(value); + } + + static convertIdentifierExpression(expression: ts.Expression): Expression { + return this.createIdentifierExpression(expression.getText()) + } + + static convertBinaryExpression(expression: ts.Expression): Expression { + return this.createBinaryExpression( + this.convertExpression(expression.left), + ts.tokenToString(expression.operatorToken.kind), + this.convertExpression(expression.right) + ) + } + + static convertNumericLiteralExpression(expression: ts.Expression): Expression { + return this.createNumericLiteralExpression(expression.getText()) + } + + static convertBigIntLiteralExpression(expression: ts.Expression): Expression { + return this.createBigIntLiteralExpression(expression.getText()) + } + + static convertStringLiteralExpression(expression: ts.Expression): Expression { + return this.createStringLiteralExpression(expression.getText()) + } + + static convertRegExLiteralExpression(expression: ts.Expression): Expression { + return this.createRegExLiteralExpression(expression.getText()) + } + + static convertUnknownExpression(expression: ts.Expression): Expression { + return this.createUnknownExpression(expression.getText()) + } + + static convertExpression(expression: ts.Expression): Expression { + if (ts.isBinaryExpression(expression)) { + return this.convertBinaryExpression(expression); + } else if (ts.isIdentifier(expression)) { + return this.convertIdentifierExpression(expression); + } else if (ts.isNumericLiteral(expression)) { + return this.convertNumericLiteralExpression(expression); + } else if (ts.isBigIntLiteral(expression)) { + return this.convertBigIntLiteralExpression(expression); + } else if (ts.isStringLiteral(expression)) { + return this.convertStringLiteralExpression(expression); + } else if (ts.isRegularExpressionLiteral(expression)) { + return this.convertRegExLiteralExpression(expression); + } else { + return this.convertUnknownExpression(expression) + } + } +} \ No newline at end of file diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts new file mode 100644 index 000000000..3d675ed41 --- /dev/null +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -0,0 +1,81 @@ +import * as declarations from "declarations"; +import { + Expression, + LiteralExpression +} from "./ast"; + +export class AstExpressionFactory { + static createIdentifierExpressionDeclarationAsExpression(value: string): Expression { + let identifier = new declarations.IdentifierEntityProto(); + identifier.setValue(value); + + let identifierExpressionProto = new declarations.IdentifierExpressionDeclarationProto(); + identifierExpressionProto.setIdentifier(identifier); + + let expression = new declarations.ExpressionDeclarationProto(); + expression.setIdentifierexpression(identifierExpressionProto); + return expression; + } + + static createBinaryExpressionDeclarationAsExpression(left: Expression, operator: string, right: Expression): Expression { + let binaryExpression = new declarations.BinaryExpressionDeclarationProto(); + binaryExpression.setLeft(left); + binaryExpression.setOperator(operator); + binaryExpression.setRight(right); + + let expression = new declarations.ExpressionDeclarationProto(); + expression.setBinaryexpression(binaryExpression); + return expression; + } + + static createUnknownExpressionDeclarationAsExpression(meta: string): Expression { + let unknownExpression = new declarations.UnknownExpressionDeclarationProto(); + unknownExpression.setMeta(meta); + + let expression = new declarations.ExpressionDeclarationProto(); + expression.setUnknownexpression(unknownExpression); + return expression; + } + + private static asExpression(literalExpression: LiteralExpression): Expression { + let expression = new declarations.ExpressionDeclarationProto(); + expression.setLiteralexpression(literalExpression); + return expression; + } + + static createNumericLiteralDeclarationAsExpression(value: string): Expression { + let numericLiteralExpression = new declarations.NumericLiteralExpressionDeclarationProto(); + numericLiteralExpression.setValue(value); + + let literalExpression = new declarations.LiteralExpressionDeclarationProto(); + literalExpression.setNumericliteral(numericLiteralExpression); + return this.asExpression(literalExpression); + } + + static createBigIntLiteralDeclarationAsExpression(value: string): Expression { + let bigIntLiteralExpression = new declarations.BigIntLiteralExpressionDeclarationProto(); + bigIntLiteralExpression.setValue(value); + + let literalExpression = new declarations.LiteralExpressionDeclarationProto(); + literalExpression.setBigintliteral(bigIntLiteralExpression); + return this.asExpression(literalExpression); + } + + static createStringLiteralDeclarationAsExpression(value: string): Expression { + let stringLiteralExpression = new declarations.StringLiteralExpressionDeclarationProto(); + stringLiteralExpression.setValue(value); + + let literalExpression = new declarations.LiteralExpressionDeclarationProto(); + literalExpression.setStringliteral(stringLiteralExpression); + return this.asExpression(literalExpression); + } + + static createRegExLiteralDeclarationAsExpression(value: string): Expression { + let regExLiteralExpression = new declarations.RegExLiteralExpressionDeclarationProto(); + regExLiteralExpression.setValue(value); + + let literalExpression = new declarations.LiteralExpressionDeclarationProto(); + literalExpression.setRegExliteral(regExLiteralExpression); + return this.asExpression(literalExpression); + } +} \ No newline at end of file diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index 1b1ed7c6d..c71b03abe 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -1,6 +1,5 @@ import * as declarations from "declarations"; import { - BinaryExpression, Block, CallSignatureDeclaration, ClassDeclaration, @@ -17,12 +16,10 @@ import { FunctionTypeDeclaration, HeritageClauseDeclaration, IdentifierEntity, - IdentifierExpression, ImportEqualsDeclaration, IndexSignatureDeclaration, InterfaceDeclaration, IntersectionTypeDeclaration, - LiteralExpression, MemberDeclaration, MethodSignatureDeclaration, ModifierDeclaration, @@ -143,78 +140,6 @@ export class AstFactory implements AstFactory { return topLevelEntity; } - createIdentifierExpressionDeclarationAsExpression(identifier: IdentifierEntity): IdentifierExpression { - let identifierExpressionProto = new declarations.IdentifierExpressionDeclarationProto(); - identifierExpressionProto.setIdentifier(identifier); - - let expression = new declarations.ExpressionDeclarationProto(); - expression.setIdentifierexpression(identifierExpressionProto); - return expression; - } - - createBinaryExpressionDeclarationAsExpression(left: Expression, operator: string, right: Expression): BinaryExpression { - let binaryExpression = new declarations.BinaryExpressionDeclarationProto(); - binaryExpression.setLeft(left); - binaryExpression.setOperator(operator); - binaryExpression.setRight(right); - - let expression = new declarations.ExpressionDeclarationProto(); - expression.setBinaryexpression(binaryExpression); - return expression; - } - - createUnknownExpressionDeclarationAsExpression(meta: string): Expression { - let unknownExpression = new declarations.UnknownExpressionDeclarationProto(); - unknownExpression.setMeta(meta); - - let expression = new declarations.ExpressionDeclarationProto(); - expression.setUnknownexpression(unknownExpression); - return expression; - } - - private asExpression(literalExpression: LiteralExpression): Expression { - let expression = new declarations.ExpressionDeclarationProto(); - expression.setLiteralexpression(literalExpression); - return expression; - } - - createNumericLiteralDeclarationAsExpression(value: string): Expression { - let numericLiteralExpression = new declarations.NumericLiteralExpressionDeclarationProto(); - numericLiteralExpression.setValue(value); - - let literalExpression = new declarations.LiteralExpressionDeclarationProto(); - literalExpression.setNumericliteral(numericLiteralExpression); - return this.asExpression(literalExpression); - } - - createBigIntLiteralDeclarationAsExpression(value: string): Expression { - let bigIntLiteralExpression = new declarations.BigIntLiteralExpressionDeclarationProto(); - bigIntLiteralExpression.setValue(value); - - let literalExpression = new declarations.LiteralExpressionDeclarationProto(); - literalExpression.setBigintliteral(bigIntLiteralExpression); - return this.asExpression(literalExpression); - } - - createStringLiteralDeclarationAsExpression(value: string): Expression { - let stringLiteralExpression = new declarations.StringLiteralExpressionDeclarationProto(); - stringLiteralExpression.setValue(value); - - let literalExpression = new declarations.LiteralExpressionDeclarationProto(); - literalExpression.setStringliteral(stringLiteralExpression); - return this.asExpression(literalExpression); - } - - createRegExLiteralDeclarationAsExpression(value: string): Expression { - let regExLiteralExpression = new declarations.RegExLiteralExpressionDeclarationProto(); - regExLiteralExpression.setValue(value); - - let literalExpression = new declarations.LiteralExpressionDeclarationProto(); - literalExpression.setRegExliteral(regExLiteralExpression); - return this.asExpression(literalExpression); - } - - createBlockDeclaration(statements: Array): Block { let block = new declarations.BlockDeclarationProto(); block.setStatementsList(statements); diff --git a/typescript/ts-converter/src/ast/ast.ts b/typescript/ts-converter/src/ast/ast.ts index a0197d9f5..12dea2a3a 100644 --- a/typescript/ts-converter/src/ast/ast.ts +++ b/typescript/ts-converter/src/ast/ast.ts @@ -114,38 +114,6 @@ export declare class PropertyDeclaration implements MemberDeclaration { serializeBinary(): Int8Array; } -export declare class IdentifierExpression implements Expression { - identifier: IdentifierEntity; - serializeBinary(): Int8Array; -} - -export declare class BinaryExpression implements Expression { - left: Expression; - operator: string; - right: Expression; - serializeBinary(): Int8Array; -} - -export declare class NumericLiteralExpression implements LiteralExpression { - value: string; - serializeBinary(): Int8Array; -} - -export declare class BigIntLiteralExpression implements LiteralExpression { - value: string; - serializeBinary(): Int8Array; -} - -export declare class StringLiteralExpression implements LiteralExpression { - value: string; - serializeBinary(): Int8Array; -} - -export declare class RegExLiteralExpression implements LiteralExpression { - value: string; - serializeBinary(): Int8Array; -} - export declare interface LiteralExpression extends Expression {} export declare interface Expression extends Declaration {} From c47ebd8706e88532a37f5bbfae9ffff4123800db Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Oct 2019 15:20:51 +0100 Subject: [PATCH 017/172] Resolve constraints with explicit types --- .../container/ConstraintContainer.kt | 18 +++++++++- .../container/ReturnConstraintContainer.kt | 14 ++------ .../resolved/BigIntTypeConstraint.kt | 3 ++ .../resolved/BooleanTypeConstraint.kt | 4 +-- .../constraint/resolved/NoTypeConstraint.kt | 3 ++ .../resolved/NumberTypeConstraint.kt | 4 +-- .../resolved/RegExTypeConstraint.kt | 3 ++ .../constraint/resolved/ResolvedConstraint.kt | 4 +-- .../resolved/StringTypeConstraint.kt | 4 +-- .../constraint/resolved/UnitTypeConstraint.kt | 5 --- .../dukat/js/type_analysis/expression.kt | 28 +++++++++++++-- .../dukat/js/type_analysis/type/types.kt | 34 +++++++++++++++++++ .../jetbrains/dukat/js/type_analysis/types.kt | 6 ++-- 13 files changed, 95 insertions(+), 35 deletions(-) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BigIntTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NoTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/RegExTypeConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/UnitTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/type/types.kt diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt index 2eca2942e..080f58ad5 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt @@ -1,6 +1,14 @@ package org.jetbrains.dukat.js.type_analysis.constraint.container import org.jetbrains.dukat.js.type_analysis.constraint.Constraint +import org.jetbrains.dukat.js.type_analysis.constraint.resolved.BigIntTypeConstraint +import org.jetbrains.dukat.js.type_analysis.constraint.resolved.BooleanTypeConstraint +import org.jetbrains.dukat.js.type_analysis.constraint.resolved.NumberTypeConstraint +import org.jetbrains.dukat.js.type_analysis.constraint.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type_analysis.type.anyNullableType +import org.jetbrains.dukat.js.type_analysis.type.booleanType +import org.jetbrains.dukat.js.type_analysis.type.numberType +import org.jetbrains.dukat.js.type_analysis.type.stringType import org.jetbrains.dukat.tsmodel.types.TypeDeclaration abstract class ConstraintContainer(protected val constraints: MutableSet = mutableSetOf()) { @@ -14,5 +22,13 @@ abstract class ConstraintContainer(protected val constraints: MutableSet numberType + constraints.contains(BigIntTypeConstraint) -> numberType + constraints.contains(BooleanTypeConstraint) -> booleanType + constraints.contains(StringTypeConstraint) -> stringType + else -> anyNullableType + } + } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt index ba5b35f5e..9b3d1b8e9 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt @@ -1,7 +1,7 @@ package org.jetbrains.dukat.js.type_analysis.constraint.container -import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type_analysis.constraint.Constraint +import org.jetbrains.dukat.js.type_analysis.type.unitType import org.jetbrains.dukat.tsmodel.types.TypeDeclaration class ReturnConstraintContainer(constraints: MutableSet = mutableSetOf()) : ConstraintContainer(constraints) { @@ -11,17 +11,9 @@ class ReturnConstraintContainer(constraints: MutableSet = mutableSet override fun resolveToType(): TypeDeclaration { return if(constraints.isEmpty()) { - TypeDeclaration( - value = IdentifierEntity("Unit"), - params = emptyList(), - nullable = false - ) + unitType } else { - TypeDeclaration( - value = IdentifierEntity("Any"), - params = emptyList(), - nullable = true - ) + super.resolveToType() } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BigIntTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BigIntTypeConstraint.kt new file mode 100644 index 000000000..c690f047c --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BigIntTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type_analysis.constraint.resolved + +object BigIntTypeConstraint : ResolvedConstraint() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BooleanTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BooleanTypeConstraint.kt index 55b766c0e..ade59c337 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BooleanTypeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BooleanTypeConstraint.kt @@ -1,5 +1,3 @@ package org.jetbrains.dukat.js.type_analysis.constraint.resolved -object BooleanTypeConstraint : ResolvedConstraint { - override val typeName = "boolean" -} \ No newline at end of file +object BooleanTypeConstraint : ResolvedConstraint() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NoTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NoTypeConstraint.kt new file mode 100644 index 000000000..c6e86b390 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NoTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type_analysis.constraint.resolved + +object NoTypeConstraint : ResolvedConstraint() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NumberTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NumberTypeConstraint.kt index 3b41a3cee..3260656bd 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NumberTypeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NumberTypeConstraint.kt @@ -1,5 +1,3 @@ package org.jetbrains.dukat.js.type_analysis.constraint.resolved -object NumberTypeConstraint : ResolvedConstraint { - override val typeName = "number" -} \ No newline at end of file +object NumberTypeConstraint : ResolvedConstraint() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/RegExTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/RegExTypeConstraint.kt new file mode 100644 index 000000000..4ac473bdd --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/RegExTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type_analysis.constraint.resolved + +object RegExTypeConstraint : ResolvedConstraint() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt index 940caf446..1b854fd82 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt @@ -2,8 +2,6 @@ package org.jetbrains.dukat.js.type_analysis.constraint.resolved import org.jetbrains.dukat.js.type_analysis.constraint.Constraint -interface ResolvedConstraint : Constraint { +abstract class ResolvedConstraint : Constraint { override fun resolve() = this - - val typeName: String } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/StringTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/StringTypeConstraint.kt index 9648ba9b5..dd77f6dbf 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/StringTypeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/StringTypeConstraint.kt @@ -1,5 +1,3 @@ package org.jetbrains.dukat.js.type_analysis.constraint.resolved -object StringTypeConstraint : ResolvedConstraint { - override val typeName = "string" -} \ No newline at end of file +object StringTypeConstraint : ResolvedConstraint() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/UnitTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/UnitTypeConstraint.kt deleted file mode 100644 index 8fdb30a93..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/UnitTypeConstraint.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.jetbrains.dukat.js.type_analysis.constraint.resolved - -object UnitTypeConstraint : ResolvedConstraint { - override val typeName = "Unit" -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt index 8b50f4144..e47fb0039 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt @@ -1,10 +1,20 @@ package org.jetbrains.dukat.js.type_analysis import org.jetbrains.dukat.js.type_analysis.constraint.Constraint +import org.jetbrains.dukat.js.type_analysis.constraint.resolved.BigIntTypeConstraint import org.jetbrains.dukat.js.type_analysis.constraint.resolved.BooleanTypeConstraint +import org.jetbrains.dukat.js.type_analysis.constraint.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type_analysis.constraint.resolved.NumberTypeConstraint +import org.jetbrains.dukat.js.type_analysis.constraint.resolved.RegExTypeConstraint +import org.jetbrains.dukat.js.type_analysis.constraint.resolved.StringTypeConstraint +import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.RegExLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration fun BinaryExpressionDeclaration.calculateConstraints() : Set { return when (operator) { @@ -14,13 +24,25 @@ fun BinaryExpressionDeclaration.calculateConstraints() : Set { -> setOf(NumberTypeConstraint) "==", "===", "!=", "!==", ">", "<", ">=", "<=" //result must be a boolean -> setOf(BooleanTypeConstraint) - else -> emptySet() + else -> setOf(NoTypeConstraint) + } +} + +fun LiteralExpressionDeclaration.calculateConstraints() : Set { + return when (this) { + is StringLiteralExpressionDeclaration -> setOf(StringTypeConstraint) + is NumericLiteralExpressionDeclaration -> setOf(NumberTypeConstraint) + is BigIntLiteralExpressionDeclaration -> setOf(BigIntTypeConstraint) + is RegExLiteralExpressionDeclaration -> setOf(RegExTypeConstraint) + else -> raiseConcern("Unexpected literal expression type <${this.javaClass}>") { setOf(NoTypeConstraint) } } } fun ExpressionDeclaration?.calculateConstraints() : Set { - return when(this) { + return when (this) { is BinaryExpressionDeclaration -> this.calculateConstraints() - else -> emptySet() + is LiteralExpressionDeclaration -> this.calculateConstraints() + null -> emptySet() + else -> setOf(NoTypeConstraint) } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/type/types.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/type/types.kt new file mode 100644 index 000000000..0350b12eb --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/type/types.kt @@ -0,0 +1,34 @@ +package org.jetbrains.dukat.js.type_analysis.type + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.tsmodel.types.TypeDeclaration + +val unitType = TypeDeclaration( + value = IdentifierEntity("Unit"), + params = emptyList(), + nullable = false +) + +val anyNullableType = TypeDeclaration( + value = IdentifierEntity("Any"), + params = emptyList(), + nullable = true +) + +val numberType = TypeDeclaration( + value = IdentifierEntity("Number"), + params = emptyList(), + nullable = false +) + +val booleanType = TypeDeclaration( + value = IdentifierEntity("Boolean"), + params = emptyList(), + nullable = false +) + +val stringType = TypeDeclaration( + value = IdentifierEntity("String"), + params = emptyList(), + nullable = false +) \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt index f8dc7be1c..30dfba294 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt @@ -23,7 +23,7 @@ import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.types.IndexSignatureDeclaration fun FunctionDeclaration.introduceTypes() : FunctionDeclaration { - if(this.body != null) { + if (this.body != null) { val returnTypeConstraints = ReturnConstraintContainer() for(statement in this.body!!.statements) { @@ -45,7 +45,7 @@ fun ConstructorDeclaration.introduceTypes() : ConstructorDeclaration { } fun MemberEntity.introduceTypes(): MemberEntity { - return when(this) { + return when (this) { is FunctionDeclaration -> this.introduceTypes() is ConstructorDeclaration -> this.introduceTypes() is PropertyDeclaration -> this @@ -59,7 +59,7 @@ fun ClassDeclaration.introduceTypes() = copy(members = members.map { it.introduc fun BlockDeclaration.introduceTypes() = copy(statements = statements.map { it.introduceTypes() }) fun TopLevelEntity.introduceTypes(): TopLevelEntity { - return when(this) { + return when (this) { is FunctionDeclaration -> this.introduceTypes() is ClassDeclaration -> this.introduceTypes() is BlockDeclaration -> this.introduceTypes() From 26f682829bfc6ccd75191a5cab9de7a2ffef7585 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Oct 2019 16:11:19 +0100 Subject: [PATCH 018/172] Convert boolean literals to TS AST --- .../src/ast/AstExpressionConverter.ts | 59 ++++++++++++++----- .../src/ast/AstExpressionFactory.ts | 9 +++ .../ts-model-proto/src/Declarations.proto | 11 +++- .../BooleanLiteralExpressionDeclaration.kt | 5 ++ .../dukat/tsmodel/factory/convertProtobuf.kt | 3 + 5 files changed, 69 insertions(+), 18 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/BooleanLiteralExpressionDeclaration.kt diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index b5557474b..826a4df99 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -3,14 +3,14 @@ import {Expression} from "./ast"; import {AstExpressionFactory} from "./AstExpressionFactory"; export class AstExpressionConverter { - static createIdentifierExpression(name: string): Expression { - return AstExpressionFactory.createIdentifierExpressionDeclarationAsExpression(name); - } - static createBinaryExpression(left: Expression, operator: string, right: Expression): Expression { return AstExpressionFactory.createBinaryExpressionDeclarationAsExpression(left, operator, right); } + static createIdentifierExpression(name: string): Expression { + return AstExpressionFactory.createIdentifierExpressionDeclarationAsExpression(name); + } + static createNumericLiteralExpression(value: string): Expression { return AstExpressionFactory.createNumericLiteralDeclarationAsExpression(value); } @@ -23,6 +23,10 @@ export class AstExpressionConverter { return AstExpressionFactory.createStringLiteralDeclarationAsExpression(value); } + static createBooleanLiteralExpression(value: boolean): Expression { + return AstExpressionFactory.createBooleanLiteralDeclarationAsExpression(value); + } + static createRegExLiteralExpression(value: string): Expression { return AstExpressionFactory.createRegExLiteralDeclarationAsExpression(value); } @@ -31,9 +35,6 @@ export class AstExpressionConverter { return AstExpressionFactory.createUnknownExpressionDeclarationAsExpression(value); } - static convertIdentifierExpression(expression: ts.Expression): Expression { - return this.createIdentifierExpression(expression.getText()) - } static convertBinaryExpression(expression: ts.Expression): Expression { return this.createBinaryExpression( @@ -43,6 +44,11 @@ export class AstExpressionConverter { ) } + static convertIdentifierExpression(expression: ts.Expression): Expression { + return this.createIdentifierExpression(expression.getText()) + } + + static convertNumericLiteralExpression(expression: ts.Expression): Expression { return this.createNumericLiteralExpression(expression.getText()) } @@ -59,23 +65,46 @@ export class AstExpressionConverter { return this.createRegExLiteralExpression(expression.getText()) } + static convertLiteralExpression(expression: ts.LiteralExpression): Expression { + if (ts.isNumericLiteral(expression)) { + return this.convertNumericLiteralExpression(expression); + } else if (ts.isBigIntLiteral(expression)) { + return this.convertBigIntLiteralExpression(expression); + } else if (ts.isStringLiteral(expression)) { + return this.convertStringLiteralExpression(expression); + } else if (ts.isRegularExpressionLiteral(expression)) { + return this.convertRegExLiteralExpression(expression); + } else { + return this.convertUnknownExpression(expression) + } + } + + + static convertToken(expression: ts.Expression): Expression { + if (expression.kind == ts.SyntaxKind.TrueKeyword) { + return this.createBooleanLiteralExpression(true) + } else if (expression.kind == ts.SyntaxKind.FalseKeyword) { + return this.createBooleanLiteralExpression(false) + } else { + return this.convertUnknownExpression(expression) + } + } + + static convertUnknownExpression(expression: ts.Expression): Expression { return this.createUnknownExpression(expression.getText()) } + static convertExpression(expression: ts.Expression): Expression { if (ts.isBinaryExpression(expression)) { return this.convertBinaryExpression(expression); } else if (ts.isIdentifier(expression)) { return this.convertIdentifierExpression(expression); - } else if (ts.isNumericLiteral(expression)) { - return this.convertNumericLiteralExpression(expression); - } else if (ts.isBigIntLiteral(expression)) { - return this.convertBigIntLiteralExpression(expression); - } else if (ts.isStringLiteral(expression)) { - return this.convertStringLiteralExpression(expression); - } else if (ts.isRegularExpressionLiteral(expression)) { - return this.convertRegExLiteralExpression(expression); + } else if (ts.isLiteralExpression(expression)) { + return this.convertLiteralExpression(expression); + } else if (ts.isToken(expression)) { + return this.convertToken(expression) } else { return this.convertUnknownExpression(expression) } diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index 3d675ed41..e29c5103b 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -70,6 +70,15 @@ export class AstExpressionFactory { return this.asExpression(literalExpression); } + static createBooleanLiteralDeclarationAsExpression(value: boolean): Expression { + let booleanLiteralExpression = new declarations.BooleanLiteralExpressionDeclarationProto(); + booleanLiteralExpression.setValue(value); + + let literalExpression = new declarations.LiteralExpressionDeclarationProto(); + literalExpression.setBooleanliteral(booleanLiteralExpression); + return this.asExpression(literalExpression); + } + static createRegExLiteralDeclarationAsExpression(value: string): Expression { let regExLiteralExpression = new declarations.RegExLiteralExpressionDeclarationProto(); regExLiteralExpression.setValue(value); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 421b451bd..2aa643849 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -176,6 +176,10 @@ message StringLiteralExpressionDeclarationProto { string value = 1; } +message BooleanLiteralExpressionDeclarationProto { + bool value = 1; +} + message NumericLiteralExpressionDeclarationProto { string value = 1; } @@ -191,9 +195,10 @@ message RegExLiteralExpressionDeclarationProto { message LiteralExpressionDeclarationProto { oneof type { StringLiteralExpressionDeclarationProto stringLiteral = 1; - NumericLiteralExpressionDeclarationProto numericLiteral = 2; - BigIntLiteralExpressionDeclarationProto bigIntLiteral = 3; - RegExLiteralExpressionDeclarationProto regExLiteral = 4; + BooleanLiteralExpressionDeclarationProto booleanLiteral = 2; + NumericLiteralExpressionDeclarationProto numericLiteral = 3; + BigIntLiteralExpressionDeclarationProto bigIntLiteral = 4; + RegExLiteralExpressionDeclarationProto regExLiteral = 5; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/BooleanLiteralExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/BooleanLiteralExpressionDeclaration.kt new file mode 100644 index 000000000..da6fbc09f --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/BooleanLiteralExpressionDeclaration.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.tsmodel.expression.literal + +data class BooleanLiteralExpressionDeclaration( + val value: Boolean +) : LiteralExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 178f28232..7467c2272 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -40,6 +40,7 @@ import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnknownExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.RegExLiteralExpressionDeclaration @@ -336,6 +337,7 @@ private fun Declarations.ParameterValueDeclarationProto.convert(): ParameterValu fun Declarations.NumericLiteralExpressionDeclarationProto.convert() = NumericLiteralExpressionDeclaration(value) fun Declarations.BigIntLiteralExpressionDeclarationProto.convert() = BigIntLiteralExpressionDeclaration(value) fun Declarations.StringLiteralExpressionDeclarationProto.convert() = StringLiteralExpressionDeclaration(value) +fun Declarations.BooleanLiteralExpressionDeclarationProto.convert() = BooleanLiteralExpressionDeclaration(value) fun Declarations.RegExLiteralExpressionDeclarationProto.convert() = RegExLiteralExpressionDeclaration(value) fun Declarations.LiteralExpressionDeclarationProto.convert() : LiteralExpressionDeclaration { @@ -343,6 +345,7 @@ fun Declarations.LiteralExpressionDeclarationProto.convert() : LiteralExpression hasNumericLiteral() -> numericLiteral.convert() hasBigIntLiteral() -> bigIntLiteral.convert() hasStringLiteral() -> stringLiteral.convert() + hasBooleanLiteral() -> booleanLiteral.convert() hasRegExLiteral() -> regExLiteral.convert() else -> throw Exception("unknown literalExpression: ${this}") } From 7a36fde5afe7defc06ac0d0ed73ae6cd98c8f268 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Oct 2019 16:27:20 +0100 Subject: [PATCH 019/172] Gather type constraint from boolean literal expression --- .../src/org/jetbrains/dukat/js/type_analysis/expression.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt index e47fb0039..6ddeeb573 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt @@ -11,6 +11,7 @@ import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.RegExLiteralExpressionDeclaration @@ -33,6 +34,7 @@ fun LiteralExpressionDeclaration.calculateConstraints() : Set { is StringLiteralExpressionDeclaration -> setOf(StringTypeConstraint) is NumericLiteralExpressionDeclaration -> setOf(NumberTypeConstraint) is BigIntLiteralExpressionDeclaration -> setOf(BigIntTypeConstraint) + is BooleanLiteralExpressionDeclaration -> setOf(BooleanTypeConstraint) is RegExLiteralExpressionDeclaration -> setOf(RegExTypeConstraint) else -> raiseConcern("Unexpected literal expression type <${this.javaClass}>") { setOf(NoTypeConstraint) } } From 6b23560051858cf00657fbcbbc3ab0cbacea020f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Oct 2019 16:29:03 +0100 Subject: [PATCH 020/172] Filter expression statements from lowerings --- .../org/jetbrains/dukat/tsLowerings/filterOutNonDeclarations.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/filterOutNonDeclarations.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/filterOutNonDeclarations.kt index 2889dd95c..5bc14be6e 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/filterOutNonDeclarations.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/filterOutNonDeclarations.kt @@ -1,6 +1,7 @@ package org.jetbrains.dukat.tsLowerings import org.jetbrains.dukat.tsmodel.ClassDeclaration +import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.ModifierDeclaration import org.jetbrains.dukat.tsmodel.ModuleDeclaration @@ -38,6 +39,7 @@ fun ModuleDeclaration.filterOutNonDeclarations(isSubModule: Boolean): ModuleDecl listOf(declaration.filterOutNonDeclarations(true)) } else emptyList() } + is ExpressionStatementDeclaration -> emptyList() else -> listOf(declaration) } }.flatten() From 823015c37fadb8d25e47ef05e378dc752bd20776 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Oct 2019 17:07:44 +0100 Subject: [PATCH 021/172] Convert unary expression --- .../src/ast/AstExpressionConverter.ts | 24 ++++++++++++ .../src/ast/AstExpressionFactory.ts | 33 ++++++++++------ .../ts-model-proto/src/Declarations.proto | 15 +++++-- .../expression/UnaryExpressionDeclaration.kt | 9 +++++ .../dukat/tsmodel/factory/convertProtobuf.kt | 39 ++++++++++++------- 5 files changed, 91 insertions(+), 29 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/UnaryExpressionDeclaration.kt diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index 826a4df99..a3bd0f1be 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -7,6 +7,10 @@ export class AstExpressionConverter { return AstExpressionFactory.createBinaryExpressionDeclarationAsExpression(left, operator, right); } + static createUnaryExpression(operand: Expression, operator: string, isPrefix: boolean) { + return AstExpressionFactory.createUnaryExpressionDeclarationAsExpression(operand, operator, isPrefix); + } + static createIdentifierExpression(name: string): Expression { return AstExpressionFactory.createIdentifierExpressionDeclarationAsExpression(name); } @@ -44,6 +48,22 @@ export class AstExpressionConverter { ) } + static convertPrefixUnaryExpression(expression: ts.Expression): Expression { + return this.createUnaryExpression( + this.convertExpression(expression.operand), + ts.tokenToString(expression.operator), + true + ) + } + + static convertPostfixUnaryExpression(expression: ts.Expression): Expression { + return this.createUnaryExpression( + this.convertExpression(expression.operand), + ts.tokenToString(expression.operator), + false + ) + } + static convertIdentifierExpression(expression: ts.Expression): Expression { return this.createIdentifierExpression(expression.getText()) } @@ -99,6 +119,10 @@ export class AstExpressionConverter { static convertExpression(expression: ts.Expression): Expression { if (ts.isBinaryExpression(expression)) { return this.convertBinaryExpression(expression); + } else if (ts.isPrefixUnaryExpression(expression)) { + return this.convertPrefixUnaryExpression(expression) + } else if (ts.isPostfixUnaryExpression(expression)) { + return this.convertPostfixUnaryExpression(expression) } else if (ts.isIdentifier(expression)) { return this.convertIdentifierExpression(expression); } else if (ts.isLiteralExpression(expression)) { diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index e29c5103b..8158575b9 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -5,6 +5,28 @@ import { } from "./ast"; export class AstExpressionFactory { + static createBinaryExpressionDeclarationAsExpression(left: Expression, operator: string, right: Expression): Expression { + let binaryExpression = new declarations.BinaryExpressionDeclarationProto(); + binaryExpression.setLeft(left); + binaryExpression.setOperator(operator); + binaryExpression.setRight(right); + + let expression = new declarations.ExpressionDeclarationProto(); + expression.setBinaryexpression(binaryExpression); + return expression; + } + + static createUnaryExpressionDeclarationAsExpression(operand: Expression, operator: string, isPrefix: boolean): Expression { + let unaryExpression = new declarations.UnaryExpressionDeclarationProto(); + unaryExpression.setOperand(operand); + unaryExpression.setOperator(operator); + unaryExpression.setIsprefix(isPrefix); + + let expression = new declarations.ExpressionDeclarationProto(); + expression.setUnaryexpression(unaryExpression); + return expression; + } + static createIdentifierExpressionDeclarationAsExpression(value: string): Expression { let identifier = new declarations.IdentifierEntityProto(); identifier.setValue(value); @@ -17,17 +39,6 @@ export class AstExpressionFactory { return expression; } - static createBinaryExpressionDeclarationAsExpression(left: Expression, operator: string, right: Expression): Expression { - let binaryExpression = new declarations.BinaryExpressionDeclarationProto(); - binaryExpression.setLeft(left); - binaryExpression.setOperator(operator); - binaryExpression.setRight(right); - - let expression = new declarations.ExpressionDeclarationProto(); - expression.setBinaryexpression(binaryExpression); - return expression; - } - static createUnknownExpressionDeclarationAsExpression(meta: string): Expression { let unknownExpression = new declarations.UnknownExpressionDeclarationProto(); unknownExpression.setMeta(meta); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 2aa643849..c0b0b8a37 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -212,16 +212,23 @@ message BinaryExpressionDeclarationProto { ExpressionDeclarationProto right = 3; } +message UnaryExpressionDeclarationProto { + ExpressionDeclarationProto operand = 1; + string operator = 2; + bool isPrefix = 3; +} + message UnknownExpressionDeclarationProto { string meta = 1; } message ExpressionDeclarationProto { oneof type { - IdentifierExpressionDeclarationProto identifierExpression = 1; - BinaryExpressionDeclarationProto binaryExpression = 2; - LiteralExpressionDeclarationProto literalExpression = 3; - UnknownExpressionDeclarationProto unknownExpression = 4; + BinaryExpressionDeclarationProto binaryExpression = 1; + UnaryExpressionDeclarationProto unaryExpression = 2; + IdentifierExpressionDeclarationProto identifierExpression = 3; + LiteralExpressionDeclarationProto literalExpression = 4; + UnknownExpressionDeclarationProto unknownExpression = 5; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/UnaryExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/UnaryExpressionDeclaration.kt new file mode 100644 index 000000000..d0472412a --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/UnaryExpressionDeclaration.kt @@ -0,0 +1,9 @@ +package org.jetbrains.dukat.tsmodel.expression + +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +data class UnaryExpressionDeclaration( + val operand: ExpressionDeclaration, + val operator: String, + val isPrefix: Boolean +) : ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 7467c2272..3c47af048 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -38,6 +38,7 @@ import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnknownExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration @@ -334,6 +335,29 @@ private fun Declarations.ParameterValueDeclarationProto.convert(): ParameterValu } } + +fun Declarations.BinaryExpressionDeclarationProto.convert() : BinaryExpressionDeclaration { + return BinaryExpressionDeclaration( + left = left.convert(), + operator = operator, + right = right.convert() + ) +} + +fun Declarations.UnaryExpressionDeclarationProto.convert() : UnaryExpressionDeclaration { + return UnaryExpressionDeclaration( + operand = operand.convert(), + operator = operator, + isPrefix = isPrefix + ) +} + +fun Declarations.IdentifierExpressionDeclarationProto.convert() : IdentifierExpressionDeclaration { + return IdentifierExpressionDeclaration( + identifier = identifier.convert() + ) +} + fun Declarations.NumericLiteralExpressionDeclarationProto.convert() = NumericLiteralExpressionDeclaration(value) fun Declarations.BigIntLiteralExpressionDeclarationProto.convert() = BigIntLiteralExpressionDeclaration(value) fun Declarations.StringLiteralExpressionDeclarationProto.convert() = StringLiteralExpressionDeclaration(value) @@ -351,20 +375,6 @@ fun Declarations.LiteralExpressionDeclarationProto.convert() : LiteralExpression } } -fun Declarations.BinaryExpressionDeclarationProto.convert() : BinaryExpressionDeclaration { - return BinaryExpressionDeclaration( - left = left.convert(), - operator = operator, - right = right.convert() - ) -} - -fun Declarations.IdentifierExpressionDeclarationProto.convert() : IdentifierExpressionDeclaration { - return IdentifierExpressionDeclaration( - identifier = identifier.convert() - ) -} - fun Declarations.UnknownExpressionDeclarationProto.convert() : UnknownExpressionDeclaration { return UnknownExpressionDeclaration( meta = meta @@ -374,6 +384,7 @@ fun Declarations.UnknownExpressionDeclarationProto.convert() : UnknownExpression fun Declarations.ExpressionDeclarationProto.convert() : ExpressionDeclaration { return when { hasBinaryExpression() -> binaryExpression.convert() + hasUnaryExpression() -> unaryExpression.convert() hasIdentifierExpression() -> identifierExpression.convert() hasLiteralExpression() -> literalExpression.convert() hasUnknownExpression() -> unknownExpression.convert() From a3ca990a2a6484123c1e97488ba4a298067fd9a4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Oct 2019 18:31:08 +0100 Subject: [PATCH 022/172] Store constraints for function parameters --- .../constraint/container/ConstraintContainer.kt | 6 ++++-- .../org/jetbrains/dukat/js/type_analysis/types.kt | 12 +++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt index 080f58ad5..4033c768d 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt @@ -11,7 +11,7 @@ import org.jetbrains.dukat.js.type_analysis.type.numberType import org.jetbrains.dukat.js.type_analysis.type.stringType import org.jetbrains.dukat.tsmodel.types.TypeDeclaration -abstract class ConstraintContainer(protected val constraints: MutableSet = mutableSetOf()) { +open class ConstraintContainer(protected val constraints: MutableSet = mutableSetOf()) { operator fun plusAssign(constraint: Constraint) { constraints += constraint } @@ -20,7 +20,9 @@ abstract class ConstraintContainer(protected val constraints: MutableSet + parameters[i].copy( + type = parameterConstraints.resolveToType() + ) + } ) } else { return this; From e3817e6a9d4a6ff2fc113512c238311116ae4d9c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Oct 2019 18:31:46 +0100 Subject: [PATCH 023/172] Get constrains from unary expressions --- .../jetbrains/dukat/js/type_analysis/expression.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt index 6ddeeb573..5bbc4ec5c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt @@ -10,6 +10,7 @@ import org.jetbrains.dukat.js.type_analysis.constraint.resolved.StringTypeConstr import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration @@ -29,6 +30,17 @@ fun BinaryExpressionDeclaration.calculateConstraints() : Set { } } +fun UnaryExpressionDeclaration.calculateConstraints() : Set { + return when (operator) { + "--", "++", "~", //result and parameters must be numbers + "-", "+" //result must be a number + -> setOf(NumberTypeConstraint) + "!" //result and parameters must be booleans + -> setOf(BooleanTypeConstraint) + else -> setOf(NoTypeConstraint) + } +} + fun LiteralExpressionDeclaration.calculateConstraints() : Set { return when (this) { is StringLiteralExpressionDeclaration -> setOf(StringTypeConstraint) @@ -43,6 +55,7 @@ fun LiteralExpressionDeclaration.calculateConstraints() : Set { fun ExpressionDeclaration?.calculateConstraints() : Set { return when (this) { is BinaryExpressionDeclaration -> this.calculateConstraints() + is UnaryExpressionDeclaration -> this.calculateConstraints() is LiteralExpressionDeclaration -> this.calculateConstraints() null -> emptySet() else -> setOf(NoTypeConstraint) From 46b88f22c46a7de33e4ef254f8d1e46dd2d4f177 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Oct 2019 13:32:14 +0100 Subject: [PATCH 024/172] Track constraints for variables throughout function body --- javascript/js-interpretation/build.gradle | 9 ++ .../dukat/js/interpretation/Scope.kt | 88 +++++++++++++++++++ javascript/js-type-analysis/build.gradle | 1 + .../js/type_analysis/constraint/Constraint.kt | 6 +- .../container/ConstraintContainer.kt | 27 ++++-- .../container/ReturnConstraintContainer.kt | 6 +- .../constraint/resolved/ResolvedConstraint.kt | 4 +- .../dukat/js/type_analysis/expression.kt | 81 +++++++++++------ .../jetbrains/dukat/js/type_analysis/types.kt | 19 ++-- 9 files changed, 191 insertions(+), 50 deletions(-) create mode 100644 javascript/js-interpretation/build.gradle create mode 100644 javascript/js-interpretation/src/org/jetbrains/dukat/js/interpretation/Scope.kt diff --git a/javascript/js-interpretation/build.gradle b/javascript/js-interpretation/build.gradle new file mode 100644 index 000000000..b092ebeb5 --- /dev/null +++ b/javascript/js-interpretation/build.gradle @@ -0,0 +1,9 @@ +plugins { + id 'kotlin' +} + +dependencies { + implementation(project(":ast-common")) + implementation(project(":panic")) + implementation(project(":ts-model")) +} \ No newline at end of file diff --git a/javascript/js-interpretation/src/org/jetbrains/dukat/js/interpretation/Scope.kt b/javascript/js-interpretation/src/org/jetbrains/dukat/js/interpretation/Scope.kt new file mode 100644 index 000000000..64c0de62f --- /dev/null +++ b/javascript/js-interpretation/src/org/jetbrains/dukat/js/interpretation/Scope.kt @@ -0,0 +1,88 @@ +package org.jetbrains.dukat.js.interpretation + +import org.jetbrains.dukat.panic.raiseConcern +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration + + +/** + * Models variable behaviour in javascript execution. + * This includes variable access in nested scopes. + * + * @param T Type of data stored for the variables. + * @property parent Parent scope of this scope. + */ +class Scope( + private val parent: Scope? = null +) { + private val scopeData = mutableMapOf() + + operator fun set(name: String, data: T?) { + scopeData[name] = data + } + + operator fun set(identifierExpression: IdentifierExpressionDeclaration, data: T?) { + this[identifierExpression.identifier.value] = data + } + + operator fun set(expression: ExpressionDeclaration, data: T?) { + return when (expression) { + is IdentifierExpressionDeclaration -> this[expression] = data + else -> raiseConcern("Cannot set variable described by expression of type <${expression::class}>") { } + } + } + + + fun assign(name: String, data: T?) { + if (scopeData.contains(name) || parent == null) { + scopeData[name] = data + } else { + parent.assign(name, data) + } + } + + fun assign(identifierExpression: IdentifierExpressionDeclaration, data: T?) { + this.assign(identifierExpression.identifier.value, data) + } + + + fun getProperty(name: String) : T? { + return scopeData[name] ?: raiseConcern("Trying to access un-set property <$name>") { null } + } + + fun getProperty(identifierExpression: IdentifierExpressionDeclaration) : T? { + return this.getProperty(identifierExpression.identifier.value) + } + + fun getProperty(identifier: LiteralExpressionDeclaration) : T? { + return when (identifier) { + is StringLiteralExpressionDeclaration -> this.getProperty(identifier.value) + is NumericLiteralExpressionDeclaration -> this.getProperty(identifier.value) + is BigIntLiteralExpressionDeclaration -> this.getProperty(identifier.value) + is BooleanLiteralExpressionDeclaration -> this.getProperty(identifier.value.toString()) + else -> raiseConcern("Cannot access property of scope using literal identifier of type <${identifier::class}>") { null } + } + } + + + operator fun get(name: String) : T? { + return scopeData[name] ?: parent?.get(name) ?: raiseConcern("Trying to get un-set variable '$name'") { null } + } + + operator fun get(identifierExpression: IdentifierExpressionDeclaration) : T? { + return this[identifierExpression.identifier.value] + } + + operator fun get(expression: ExpressionDeclaration): T? { + return when (expression) { + is IdentifierExpressionDeclaration -> this[expression] + else -> raiseConcern("Cannot get variable described by expression of type <${expression::class}>") { null } + } + } + +} diff --git a/javascript/js-type-analysis/build.gradle b/javascript/js-type-analysis/build.gradle index b092ebeb5..72b20ee23 100644 --- a/javascript/js-type-analysis/build.gradle +++ b/javascript/js-type-analysis/build.gradle @@ -4,6 +4,7 @@ plugins { dependencies { implementation(project(":ast-common")) + implementation(project(":js-interpretation")) implementation(project(":panic")) implementation(project(":ts-model")) } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/Constraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/Constraint.kt index 6088049f3..5d53965e7 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/Constraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/Constraint.kt @@ -1,7 +1,3 @@ package org.jetbrains.dukat.js.type_analysis.constraint -import org.jetbrains.dukat.js.type_analysis.constraint.resolved.ResolvedConstraint - -interface Constraint { - fun resolve(): ResolvedConstraint -} \ No newline at end of file +interface Constraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt index 4033c768d..dc839e5a5 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt @@ -11,12 +11,14 @@ import org.jetbrains.dukat.js.type_analysis.type.numberType import org.jetbrains.dukat.js.type_analysis.type.stringType import org.jetbrains.dukat.tsmodel.types.TypeDeclaration -open class ConstraintContainer(protected val constraints: MutableSet = mutableSetOf()) { - operator fun plusAssign(constraint: Constraint) { +open class ConstraintContainer(protected val constraints: MutableSet) : Constraint { + constructor(vararg params: Constraint) : this(mutableSetOf(*params)) + + open operator fun plusAssign(constraint: Constraint) { constraints += constraint } - operator fun plusAssign(newConstraints: Collection) { + open operator fun plusAssign(newConstraints: Collection) { constraints.addAll(newConstraints) } @@ -24,12 +26,23 @@ open class ConstraintContainer(protected val constraints: MutableSet return ConstraintContainer(constraints) } + open fun getFlatConstraints() : List { + return constraints.flatMap { constraint -> + if(constraint is ConstraintContainer) { + constraint.getFlatConstraints() + } else { + listOf(constraint) + } + } + } + open fun resolveToType() : TypeDeclaration { + val flatConstraints = getFlatConstraints() return when { - constraints.contains(NumberTypeConstraint) -> numberType - constraints.contains(BigIntTypeConstraint) -> numberType - constraints.contains(BooleanTypeConstraint) -> booleanType - constraints.contains(StringTypeConstraint) -> stringType + flatConstraints.contains(NumberTypeConstraint) -> numberType + flatConstraints.contains(BigIntTypeConstraint) -> numberType + flatConstraints.contains(BooleanTypeConstraint) -> booleanType + flatConstraints.contains(StringTypeConstraint) -> stringType else -> anyNullableType } } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt index 9b3d1b8e9..4b20c152b 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt @@ -4,13 +4,15 @@ import org.jetbrains.dukat.js.type_analysis.constraint.Constraint import org.jetbrains.dukat.js.type_analysis.type.unitType import org.jetbrains.dukat.tsmodel.types.TypeDeclaration -class ReturnConstraintContainer(constraints: MutableSet = mutableSetOf()) : ConstraintContainer(constraints) { +class ReturnConstraintContainer(constraints: MutableSet) : ConstraintContainer(constraints) { + constructor(vararg params: Constraint) : this(mutableSetOf(*params)) + override fun copy(): ConstraintContainer { return ReturnConstraintContainer(constraints) } override fun resolveToType(): TypeDeclaration { - return if(constraints.isEmpty()) { + return if(getFlatConstraints().isEmpty()) { unitType } else { super.resolveToType() diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt index 1b854fd82..aac043d25 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt @@ -2,6 +2,4 @@ package org.jetbrains.dukat.js.type_analysis.constraint.resolved import org.jetbrains.dukat.js.type_analysis.constraint.Constraint -abstract class ResolvedConstraint : Constraint { - override fun resolve() = this -} \ No newline at end of file +abstract class ResolvedConstraint : Constraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt index 5bbc4ec5c..291e673d9 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt @@ -1,6 +1,7 @@ package org.jetbrains.dukat.js.type_analysis -import org.jetbrains.dukat.js.type_analysis.constraint.Constraint +import org.jetbrains.dukat.js.interpretation.Scope +import org.jetbrains.dukat.js.type_analysis.constraint.container.ConstraintContainer import org.jetbrains.dukat.js.type_analysis.constraint.resolved.BigIntTypeConstraint import org.jetbrains.dukat.js.type_analysis.constraint.resolved.BooleanTypeConstraint import org.jetbrains.dukat.js.type_analysis.constraint.resolved.NoTypeConstraint @@ -10,6 +11,7 @@ import org.jetbrains.dukat.js.type_analysis.constraint.resolved.StringTypeConstr import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration @@ -18,46 +20,69 @@ import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDe import org.jetbrains.dukat.tsmodel.expression.literal.RegExLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration -fun BinaryExpressionDeclaration.calculateConstraints() : Set { +fun BinaryExpressionDeclaration.calculateConstraints(scope: Scope) : ConstraintContainer { + val rightConstraints = right.calculateConstraints(scope) + left.calculateConstraints(scope) + return when (operator) { - "=" -> right.calculateConstraints() - "-", "*", "/", "**", "%", "++", "--", "-=", "*=", "/=", "%=", "**=", //result and parameters must be numbers - "&", "|", "^", "<<", ">>" //result must be a number - -> setOf(NumberTypeConstraint) - "==", "===", "!=", "!==", ">", "<", ">=", "<=" //result must be a boolean - -> setOf(BooleanTypeConstraint) - else -> setOf(NoTypeConstraint) + "=" -> { + scope[left] = rightConstraints + rightConstraints + } + "-", "*", "/", "**", "%", "++", "--", "-=", "*=", "/=", "%=", "**=" -> { + scope[right]?.plusAssign(NumberTypeConstraint) + scope[left]?.plusAssign(NumberTypeConstraint) + ConstraintContainer(NumberTypeConstraint) + } + "&", "|", "^", "<<", ">>" -> { + ConstraintContainer(NumberTypeConstraint) + } + "==", "===", "!=", "!==", ">", "<", ">=", "<=" -> { + ConstraintContainer(BooleanTypeConstraint) + } + else -> { + ConstraintContainer(NoTypeConstraint) + } } } -fun UnaryExpressionDeclaration.calculateConstraints() : Set { +fun UnaryExpressionDeclaration.calculateConstraints(scope: Scope) : ConstraintContainer { return when (operator) { - "--", "++", "~", //result and parameters must be numbers - "-", "+" //result must be a number - -> setOf(NumberTypeConstraint) - "!" //result and parameters must be booleans - -> setOf(BooleanTypeConstraint) - else -> setOf(NoTypeConstraint) + "--", "++", "~" -> { + scope[operand]?.plusAssign(NumberTypeConstraint) + ConstraintContainer(NumberTypeConstraint) + } + "-", "+" -> { + ConstraintContainer(NumberTypeConstraint) + } + "!" -> { + scope[operand]?.plusAssign(BooleanTypeConstraint) + ConstraintContainer(BooleanTypeConstraint) + } + else -> { + ConstraintContainer(NoTypeConstraint) + } } } -fun LiteralExpressionDeclaration.calculateConstraints() : Set { +fun LiteralExpressionDeclaration.calculateConstraints() : ConstraintContainer { return when (this) { - is StringLiteralExpressionDeclaration -> setOf(StringTypeConstraint) - is NumericLiteralExpressionDeclaration -> setOf(NumberTypeConstraint) - is BigIntLiteralExpressionDeclaration -> setOf(BigIntTypeConstraint) - is BooleanLiteralExpressionDeclaration -> setOf(BooleanTypeConstraint) - is RegExLiteralExpressionDeclaration -> setOf(RegExTypeConstraint) - else -> raiseConcern("Unexpected literal expression type <${this.javaClass}>") { setOf(NoTypeConstraint) } + is StringLiteralExpressionDeclaration -> ConstraintContainer(StringTypeConstraint) + is NumericLiteralExpressionDeclaration -> ConstraintContainer(NumberTypeConstraint) + is BigIntLiteralExpressionDeclaration -> ConstraintContainer(BigIntTypeConstraint) + is BooleanLiteralExpressionDeclaration -> ConstraintContainer(BooleanTypeConstraint) + is RegExLiteralExpressionDeclaration -> ConstraintContainer(RegExTypeConstraint) + else -> raiseConcern("Unexpected literal expression type <${this.javaClass}>") { ConstraintContainer(NoTypeConstraint) } } } -fun ExpressionDeclaration?.calculateConstraints() : Set { +fun ExpressionDeclaration?.calculateConstraints(scope: Scope) : ConstraintContainer { return when (this) { - is BinaryExpressionDeclaration -> this.calculateConstraints() - is UnaryExpressionDeclaration -> this.calculateConstraints() + is IdentifierExpressionDeclaration -> scope[this] ?: ConstraintContainer(NoTypeConstraint) + is BinaryExpressionDeclaration -> this.calculateConstraints(scope) + is UnaryExpressionDeclaration -> this.calculateConstraints(scope) is LiteralExpressionDeclaration -> this.calculateConstraints() - null -> emptySet() - else -> setOf(NoTypeConstraint) + null -> ConstraintContainer() + else -> ConstraintContainer(NoTypeConstraint) } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt index e39654ff2..bdb7e01b9 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt @@ -2,6 +2,7 @@ package org.jetbrains.dukat.js.type_analysis import org.jetbrains.dukat.astCommon.MemberEntity import org.jetbrains.dukat.astCommon.TopLevelEntity +import org.jetbrains.dukat.js.interpretation.Scope import org.jetbrains.dukat.js.type_analysis.constraint.container.ConstraintContainer import org.jetbrains.dukat.js.type_analysis.constraint.container.ReturnConstraintContainer import org.jetbrains.dukat.panic.raiseConcern @@ -26,14 +27,21 @@ import org.jetbrains.dukat.tsmodel.types.IndexSignatureDeclaration fun FunctionDeclaration.introduceTypes() : FunctionDeclaration { if (this.body != null) { - val returnTypeConstraints = ReturnConstraintContainer() - val parameterConstraintContainers = List(parameters.size) { - ConstraintContainer() + val functionScope = Scope() + + var returnTypeConstraints = ReturnConstraintContainer() + val parameterConstraintContainers = MutableList(parameters.size) { i -> + // Store constraints of parameters in scope, + // and in parameter list (in case the variable is replaced) + val parameterConstraintContainer = ConstraintContainer() + functionScope[parameters[i].name] = parameterConstraintContainer + parameterConstraintContainer } for(statement in this.body!!.statements) { when(statement) { - is ReturnStatementDeclaration -> returnTypeConstraints += statement.expression.calculateConstraints() + is ExpressionStatementDeclaration -> statement.expression.calculateConstraints(functionScope) + is ReturnStatementDeclaration -> returnTypeConstraints = ReturnConstraintContainer(statement.expression.calculateConstraints(functionScope)) } } @@ -51,6 +59,7 @@ fun FunctionDeclaration.introduceTypes() : FunctionDeclaration { } fun ConstructorDeclaration.introduceTypes() : ConstructorDeclaration { + // TODO add body to constructor in AST and process it like a function return this } @@ -74,7 +83,7 @@ fun TopLevelEntity.introduceTypes(): TopLevelEntity { is ClassDeclaration -> this.introduceTypes() is BlockDeclaration -> this.introduceTypes() is ModuleDeclaration -> this.introduceTypes() - is InterfaceDeclaration -> this //TODO check if this needs modification + is InterfaceDeclaration, //TODO check if this needs modification is VariableDeclaration, is EnumDeclaration, is ExportAssignmentDeclaration, From 5368477afb011c7bbb0f4c808b705110e56b39bb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Oct 2019 13:49:28 +0100 Subject: [PATCH 025/172] Add js-interpretation module --- settings.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/settings.gradle b/settings.gradle index 958783ea9..63ee2053f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -53,6 +53,7 @@ include 'idl-parser' include 'idl-reference-resolver' include 'interop' include 'itertools' +include 'js-interpretation' include 'js-type-analysis' include 'logging' include 'model-lowerings' @@ -77,6 +78,7 @@ project(':idl-models').projectDir = file("$rootDir/idl/idl-models") project(':idl-parser').projectDir = file("$rootDir/idl/idl-parser") project(':idl-reference-resolver').projectDir = file("$rootDir/idl/idl-reference-resolver") +project(':js-interpretation').projectDir = file("$rootDir/javascript/js-interpretation") project(':js-type-analysis').projectDir = file("$rootDir/javascript/js-type-analysis") project(':ts-ast-declarations').projectDir = file("$rootDir/typescript/ts-ast-declarations") From e5acd621cec3b19e0d171bfb9b6710056e855161 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Oct 2019 14:00:08 +0100 Subject: [PATCH 026/172] Make BlockDelcaration hold TopLevelDeclarations, instead of TopLevelEntities --- .../src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt index c7d6a7a08..ddc3e0acc 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/BlockDeclaration.kt @@ -1,7 +1,5 @@ package org.jetbrains.dukat.tsmodel -import org.jetbrains.dukat.astCommon.TopLevelEntity - data class BlockDeclaration( - val statements: List -) : TopLevelEntity \ No newline at end of file + val statements: List +) : TopLevelDeclaration \ No newline at end of file From be5c52406f5a5a674f9331b0c31356114f3e9381 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Oct 2019 14:08:22 +0100 Subject: [PATCH 027/172] Fix BlockDeclaration containing TopLevelDeclarations, instead of TopLevelEntities --- .../src/org/jetbrains/dukat/js/type_analysis/types.kt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt index bdb7e01b9..ea9a5a19f 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt @@ -1,7 +1,5 @@ package org.jetbrains.dukat.js.type_analysis -import org.jetbrains.dukat.astCommon.MemberEntity -import org.jetbrains.dukat.astCommon.TopLevelEntity import org.jetbrains.dukat.js.interpretation.Scope import org.jetbrains.dukat.js.type_analysis.constraint.container.ConstraintContainer import org.jetbrains.dukat.js.type_analysis.constraint.container.ReturnConstraintContainer @@ -18,9 +16,10 @@ import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.ImportEqualsDeclaration import org.jetbrains.dukat.tsmodel.InterfaceDeclaration -import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.MemberDeclaration import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration +import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.TypeAliasDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.types.IndexSignatureDeclaration @@ -63,7 +62,7 @@ fun ConstructorDeclaration.introduceTypes() : ConstructorDeclaration { return this } -fun MemberEntity.introduceTypes(): MemberEntity { +fun MemberDeclaration.introduceTypes(): MemberDeclaration { return when (this) { is FunctionDeclaration -> this.introduceTypes() is ConstructorDeclaration -> this.introduceTypes() @@ -77,7 +76,7 @@ fun ClassDeclaration.introduceTypes() = copy(members = members.map { it.introduc fun BlockDeclaration.introduceTypes() = copy(statements = statements.map { it.introduceTypes() }) -fun TopLevelEntity.introduceTypes(): TopLevelEntity { +fun TopLevelDeclaration.introduceTypes(): TopLevelDeclaration { return when (this) { is FunctionDeclaration -> this.introduceTypes() is ClassDeclaration -> this.introduceTypes() From ad27139af35777f60a437f625d80df460eced9e2 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Oct 2019 14:43:17 +0100 Subject: [PATCH 028/172] Introduce types in interface members --- .../src/org/jetbrains/dukat/js/type_analysis/types.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt index ea9a5a19f..9705134bf 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt @@ -74,15 +74,17 @@ fun MemberDeclaration.introduceTypes(): MemberDeclaration { fun ClassDeclaration.introduceTypes() = copy(members = members.map { it.introduceTypes() }) +fun InterfaceDeclaration.introduceTypes() = copy(members = members.map { it.introduceTypes() }) + fun BlockDeclaration.introduceTypes() = copy(statements = statements.map { it.introduceTypes() }) fun TopLevelDeclaration.introduceTypes(): TopLevelDeclaration { return when (this) { is FunctionDeclaration -> this.introduceTypes() - is ClassDeclaration -> this.introduceTypes() is BlockDeclaration -> this.introduceTypes() + is ClassDeclaration -> this.introduceTypes() + is InterfaceDeclaration -> this.introduceTypes() is ModuleDeclaration -> this.introduceTypes() - is InterfaceDeclaration, //TODO check if this needs modification is VariableDeclaration, is EnumDeclaration, is ExportAssignmentDeclaration, From 250bb83e2ea44a0c3262de5c3aea15fd685870d7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Oct 2019 14:59:31 +0100 Subject: [PATCH 029/172] Convert variable initializers --- typescript/ts-converter/src/AstConverter.ts | 1 + typescript/ts-converter/src/ast/AstFactory.ts | 5 ++++- typescript/ts-model-proto/src/Declarations.proto | 3 ++- .../org/jetbrains/dukat/tsmodel/VariableDeclaration.kt | 1 + .../jetbrains/dukat/tsmodel/factory/convertProtobuf.kt | 10 +++++++++- 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index 8a3b3b311..e99faf287 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -798,6 +798,7 @@ export class AstConverter { declaration.name.getText(), this.convertType(declaration.type), this.convertModifiers(statement.modifiers), + declaration.initializer == null ? null : AstExpressionConverter.convertExpression(declaration.initializer), this.exportContext.getUID(declaration) )); } diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index c71b03abe..da881ee91 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -446,11 +446,14 @@ export class AstFactory implements AstFactory { return memberProto; } - declareVariable(name: string, type: ParameterValue, modifiers: Array, uid: String): VariableDeclaration { + declareVariable(name: string, type: ParameterValue, modifiers: Array, initializer: Expression | null, uid: String): VariableDeclaration { let variableDeclaration = new declarations.VariableDeclarationProto(); variableDeclaration.setName(name); variableDeclaration.setType(type); variableDeclaration.setModifiersList(modifiers); + if(initializer) { + variableDeclaration.setInitializer(initializer); + } variableDeclaration.setUid(uid); let topLevelEntity = new declarations.TopLevelEntityProto(); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 15b7c50cc..ac5bbf416 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -246,7 +246,8 @@ message VariableDeclarationProto { string name = 1; ParameterValueDeclarationProto type = 2; repeated ModifierDeclarationProto modifiers = 3; - string uid = 4; + ExpressionDeclarationProto initializer = 4; + string uid = 5; } message TypeAliasDeclarationProto { diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/VariableDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/VariableDeclaration.kt index 4e384de9c..663b950fa 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/VariableDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/VariableDeclaration.kt @@ -7,6 +7,7 @@ data class VariableDeclaration( val name: String, val type: ParameterValueDeclaration, val modifiers: List, + val initializer: ExpressionDeclaration?, override val uid: String ) : TopLevelDeclaration, WithUidDeclaration, ParameterOwnerDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 12633e4b5..631adcd7b 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -150,7 +150,15 @@ fun Declarations.TypeAliasDeclarationProto.convert(): TypeAliasDeclaration { } fun Declarations.VariableDeclarationProto.convert(): VariableDeclaration { - return VariableDeclaration(name, type.convert(), modifiersList.map { it.convert() }, uid) + return VariableDeclaration( + name, + type.convert(), + modifiersList.map { it.convert() }, + if (hasInitializer()) { + initializer?.convert() + } else null, + uid + ) } fun Declarations.EnumDeclaration.convert(): EnumDeclaration { From ae900c634fa5865402a7c3428c581a678dc45ccb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Oct 2019 15:23:36 +0100 Subject: [PATCH 030/172] Track type constraints of variables created in function bodies --- .../src/org/jetbrains/dukat/js/type_analysis/types.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt index 9705134bf..64b8e601b 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt @@ -5,6 +5,7 @@ import org.jetbrains.dukat.js.type_analysis.constraint.container.ConstraintConta import org.jetbrains.dukat.js.type_analysis.constraint.container.ReturnConstraintContainer import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.BlockDeclaration +import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.ConstructorDeclaration import org.jetbrains.dukat.tsmodel.EnumDeclaration @@ -17,6 +18,7 @@ import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.ImportEqualsDeclaration import org.jetbrains.dukat.tsmodel.InterfaceDeclaration import org.jetbrains.dukat.tsmodel.MemberDeclaration +import org.jetbrains.dukat.tsmodel.MethodSignatureDeclaration import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration import org.jetbrains.dukat.tsmodel.TopLevelDeclaration @@ -39,8 +41,10 @@ fun FunctionDeclaration.introduceTypes() : FunctionDeclaration { for(statement in this.body!!.statements) { when(statement) { + is VariableDeclaration -> functionScope[statement.name] = statement.initializer.calculateConstraints(functionScope) is ExpressionStatementDeclaration -> statement.expression.calculateConstraints(functionScope) is ReturnStatementDeclaration -> returnTypeConstraints = ReturnConstraintContainer(statement.expression.calculateConstraints(functionScope)) + else -> raiseConcern("Cannot derive types in function with statement of type <${statement::class}>") { } } } @@ -68,7 +72,9 @@ fun MemberDeclaration.introduceTypes(): MemberDeclaration { is ConstructorDeclaration -> this.introduceTypes() is PropertyDeclaration -> this is IndexSignatureDeclaration -> this - else -> raiseConcern("Unexpected member entity type <${this.javaClass}>") { this } + is MethodSignatureDeclaration -> this + is CallSignatureDeclaration -> this + else -> raiseConcern("Unexpected member entity type <${this::class}>") { this } } } @@ -92,7 +98,7 @@ fun TopLevelDeclaration.introduceTypes(): TopLevelDeclaration { is TypeAliasDeclaration, is ReturnStatementDeclaration, is ExpressionStatementDeclaration -> this - else -> raiseConcern("Unexpected top level entity type <${this.javaClass}>") { this } + else -> raiseConcern("Unexpected top level entity type <${this::class}>") { this } } } From f88c57433ca15c6e6a370ad1c7c1e4fae815932c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Oct 2019 15:24:15 +0100 Subject: [PATCH 031/172] Change use of .javaClass to ::class --- .../src/org/jetbrains/dukat/js/type_analysis/expression.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt index 291e673d9..784ef0ead 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt @@ -72,7 +72,7 @@ fun LiteralExpressionDeclaration.calculateConstraints() : ConstraintContainer { is BigIntLiteralExpressionDeclaration -> ConstraintContainer(BigIntTypeConstraint) is BooleanLiteralExpressionDeclaration -> ConstraintContainer(BooleanTypeConstraint) is RegExLiteralExpressionDeclaration -> ConstraintContainer(RegExTypeConstraint) - else -> raiseConcern("Unexpected literal expression type <${this.javaClass}>") { ConstraintContainer(NoTypeConstraint) } + else -> raiseConcern("Unexpected literal expression type <${this::class}>") { ConstraintContainer(NoTypeConstraint) } } } From cdfcc095e78c30327928404ec0dba3813aa13486 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Nov 2019 12:16:50 +0100 Subject: [PATCH 032/172] Add qualifier expressions --- .../dukat/ast/model/nodes/ParameterNode.kt | 1 - .../src/ast/AstExpressionConverter.ts | 34 +++++++++++++------ .../src/ast/AstExpressionFactory.ts | 32 ++++++++++++----- .../ts-model-proto/src/Declarations.proto | 6 ++-- .../IdentifierExpressionDeclaration.kt | 5 ++- .../name/NameExpressionDeclaration.kt | 5 +++ .../name/QualifierExpressionDeclaration.kt | 7 ++++ .../dukat/tsmodel/factory/convertProtobuf.kt | 16 +++++---- .../dukat/nodeIntroduction/introduceNodes.kt | 3 -- 9 files changed, 75 insertions(+), 34 deletions(-) rename typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/{ => name}/IdentifierExpressionDeclaration.kt (52%) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/name/NameExpressionDeclaration.kt create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/name/QualifierExpressionDeclaration.kt diff --git a/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/nodes/ParameterNode.kt b/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/nodes/ParameterNode.kt index 89bd7e274..9bd33b431 100644 --- a/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/nodes/ParameterNode.kt +++ b/typescript/ts-ast-declarations/src/org/jetbrains/dukat/ast/model/nodes/ParameterNode.kt @@ -3,7 +3,6 @@ package org.jetbrains.dukat.ast.model.nodes import org.jetbrains.dukat.astCommon.Entity import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.tsmodel.ParameterDeclaration -import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnknownExpressionDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index a3bd0f1be..3d012e2b8 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -1,5 +1,5 @@ import * as ts from "typescript-services-api"; -import {Expression} from "./ast"; +import {Expression, NameEntity} from "./ast"; import {AstExpressionFactory} from "./AstExpressionFactory"; export class AstExpressionConverter { @@ -11,8 +11,8 @@ export class AstExpressionConverter { return AstExpressionFactory.createUnaryExpressionDeclarationAsExpression(operand, operator, isPrefix); } - static createIdentifierExpression(name: string): Expression { - return AstExpressionFactory.createIdentifierExpressionDeclarationAsExpression(name); + static createNameExpression(name: NameEntity): Expression { + return AstExpressionFactory.createNameExpressionDeclarationAsExpression(name) } static createNumericLiteralExpression(value: string): Expression { @@ -40,7 +40,7 @@ export class AstExpressionConverter { } - static convertBinaryExpression(expression: ts.Expression): Expression { + static convertBinaryExpression(expression: ts.BinaryExpression): Expression { return this.createBinaryExpression( this.convertExpression(expression.left), ts.tokenToString(expression.operatorToken.kind), @@ -48,7 +48,7 @@ export class AstExpressionConverter { ) } - static convertPrefixUnaryExpression(expression: ts.Expression): Expression { + static convertPrefixUnaryExpression(expression: ts.PrefixUnaryExpression): Expression { return this.createUnaryExpression( this.convertExpression(expression.operand), ts.tokenToString(expression.operator), @@ -56,7 +56,7 @@ export class AstExpressionConverter { ) } - static convertPostfixUnaryExpression(expression: ts.Expression): Expression { + static convertPostfixUnaryExpression(expression: ts.PostfixUnaryExpression): Expression { return this.createUnaryExpression( this.convertExpression(expression.operand), ts.tokenToString(expression.operator), @@ -64,10 +64,24 @@ export class AstExpressionConverter { ) } - static convertIdentifierExpression(expression: ts.Expression): Expression { - return this.createIdentifierExpression(expression.getText()) + static convertNameExpression(name: ts.EntityName): Expression { + return this.createNameExpression( + this.convertEntityName(name) + ) } + static convertEntityName(entityName: ts.EntityName): NameEntity { + if (ts.isQualifiedName(entityName)) { + return AstExpressionFactory.createQualifierAsNameEntity( + this.convertEntityName(entityName.left), + this.convertEntityName(entityName.right).getIdentifier() + ) + } else { + return AstExpressionFactory.createIdentifierAsNameEntity( + entityName.getText() + ) + } + } static convertNumericLiteralExpression(expression: ts.Expression): Expression { return this.createNumericLiteralExpression(expression.getText()) @@ -123,8 +137,8 @@ export class AstExpressionConverter { return this.convertPrefixUnaryExpression(expression) } else if (ts.isPostfixUnaryExpression(expression)) { return this.convertPostfixUnaryExpression(expression) - } else if (ts.isIdentifier(expression)) { - return this.convertIdentifierExpression(expression); + } else if (ts.isIdentifier(expression) || ts.isQualifiedName(expression)) { + return this.convertNameExpression(expression); } else if (ts.isLiteralExpression(expression)) { return this.convertLiteralExpression(expression); } else if (ts.isToken(expression)) { diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index 8158575b9..78af83f5f 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -1,7 +1,7 @@ import * as declarations from "declarations"; import { - Expression, - LiteralExpression + Expression, IdentifierEntity, + LiteralExpression, NameEntity } from "./ast"; export class AstExpressionFactory { @@ -27,15 +27,31 @@ export class AstExpressionFactory { return expression; } - static createIdentifierExpressionDeclarationAsExpression(value: string): Expression { - let identifier = new declarations.IdentifierEntityProto(); - identifier.setValue(value); + static createQualifierAsNameEntity(left: NameEntity, right: IdentifierEntity): NameEntity { + let qualifier = new declarations.QualifierEntityProto(); + qualifier.setLeft(left); + qualifier.setRight(right); - let identifierExpressionProto = new declarations.IdentifierExpressionDeclarationProto(); - identifierExpressionProto.setIdentifier(identifier); + let nameEntity = new declarations.NameEntityProto(); + nameEntity.setQualifier(qualifier); + return nameEntity; + } + + static createIdentifierAsNameEntity(value: string): NameEntity { + let identifierProto = new declarations.IdentifierEntityProto(); + identifierProto.setValue(value); + + let nameEntity = new declarations.NameEntityProto(); + nameEntity.setIdentifier(identifierProto); + return nameEntity; + } + + static createNameExpressionDeclarationAsExpression(name: NameEntity): Expression { + let nameExpressionProto = new declarations.NameExpressionDeclarationProto(); + nameExpressionProto.setName(name); let expression = new declarations.ExpressionDeclarationProto(); - expression.setIdentifierexpression(identifierExpressionProto); + expression.setNameexpression(nameExpressionProto); return expression; } diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 5b437e150..7bbba9e5d 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -201,8 +201,8 @@ message LiteralExpressionDeclarationProto { } } -message IdentifierExpressionDeclarationProto { - IdentifierEntityProto identifier = 1; +message NameExpressionDeclarationProto { + NameEntityProto name = 1; } message BinaryExpressionDeclarationProto { @@ -225,7 +225,7 @@ message ExpressionDeclarationProto { oneof type { BinaryExpressionDeclarationProto binaryExpression = 1; UnaryExpressionDeclarationProto unaryExpression = 2; - IdentifierExpressionDeclarationProto identifierExpression = 3; + NameExpressionDeclarationProto nameExpression = 3; LiteralExpressionDeclarationProto literalExpression = 4; UnknownExpressionDeclarationProto unknownExpression = 5; } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/IdentifierExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/name/IdentifierExpressionDeclaration.kt similarity index 52% rename from typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/IdentifierExpressionDeclaration.kt rename to typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/name/IdentifierExpressionDeclaration.kt index ed36a4da3..2e3ce45cb 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/IdentifierExpressionDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/name/IdentifierExpressionDeclaration.kt @@ -1,8 +1,7 @@ -package org.jetbrains.dukat.tsmodel.expression +package org.jetbrains.dukat.tsmodel.expression.name import org.jetbrains.dukat.astCommon.IdentifierEntity -import org.jetbrains.dukat.tsmodel.ExpressionDeclaration data class IdentifierExpressionDeclaration( val identifier: IdentifierEntity -) : ExpressionDeclaration \ No newline at end of file +) : NameExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/name/NameExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/name/NameExpressionDeclaration.kt new file mode 100644 index 000000000..57c23199e --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/name/NameExpressionDeclaration.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.tsmodel.expression.name + +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +interface NameExpressionDeclaration : ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/name/QualifierExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/name/QualifierExpressionDeclaration.kt new file mode 100644 index 000000000..eaed0d8cb --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/name/QualifierExpressionDeclaration.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.tsmodel.expression.name + +import org.jetbrains.dukat.astCommon.QualifierEntity + +data class QualifierExpressionDeclaration( + val qualifier: QualifierEntity +) : NameExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 7a0a22ab9..962e76d2e 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -36,7 +36,7 @@ import org.jetbrains.dukat.tsmodel.TypeAliasDeclaration import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration -import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnknownExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration @@ -45,6 +45,8 @@ import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclarati import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.RegExLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.name.NameExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.name.QualifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration import org.jetbrains.dukat.tsmodel.types.IndexSignatureDeclaration import org.jetbrains.dukat.tsmodel.types.IntersectionTypeDeclaration @@ -356,10 +358,12 @@ fun Declarations.UnaryExpressionDeclarationProto.convert() : UnaryExpressionDecl ) } -fun Declarations.IdentifierExpressionDeclarationProto.convert() : IdentifierExpressionDeclaration { - return IdentifierExpressionDeclaration( - identifier = identifier.convert() - ) +fun Declarations.NameExpressionDeclarationProto.convert() : NameExpressionDeclaration { + return when { + name.hasIdentifier() -> IdentifierExpressionDeclaration(identifier = name.identifier.convert()) + name.hasQualifier() -> QualifierExpressionDeclaration(qualifier = name.qualifier.convert()) + else -> throw Exception("unknown nameExpression: ${this}") + } } fun Declarations.NumericLiteralExpressionDeclarationProto.convert() = NumericLiteralExpressionDeclaration(value) @@ -389,7 +393,7 @@ fun Declarations.ExpressionDeclarationProto.convert() : ExpressionDeclaration { return when { hasBinaryExpression() -> binaryExpression.convert() hasUnaryExpression() -> unaryExpression.convert() - hasIdentifierExpression() -> identifierExpression.convert() + hasNameExpression() -> nameExpression.convert() hasLiteralExpression() -> literalExpression.convert() hasUnknownExpression() -> unknownExpression.convert() else -> throw Exception("unknown expression: ${this}") diff --git a/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt b/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt index 9fe07d7c6..fdd99b8ff 100644 --- a/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt +++ b/typescript/ts-node-introduction/src/org/jetbrains/dukat/nodeIntroduction/introduceNodes.kt @@ -45,7 +45,6 @@ import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.ConstructorDeclaration import org.jetbrains.dukat.tsmodel.DefinitionInfoDeclaration import org.jetbrains.dukat.tsmodel.EnumDeclaration -import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.GeneratedInterfaceDeclaration import org.jetbrains.dukat.tsmodel.HeritageClauseDeclaration @@ -61,8 +60,6 @@ import org.jetbrains.dukat.tsmodel.SourceSetDeclaration import org.jetbrains.dukat.tsmodel.TypeAliasDeclaration import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration -import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration -import org.jetbrains.dukat.tsmodel.expression.UnknownExpressionDeclaration import org.jetbrains.dukat.tsmodel.types.IndexSignatureDeclaration import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration import org.jetbrains.dukat.tsmodel.types.TypeDeclaration From 7266a46b57ecc1c9f45e6fcc7e8c85123eff23cf Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Nov 2019 14:00:41 +0100 Subject: [PATCH 033/172] Add PropertyAccessExpressionDeclaration and ElementAccessExpressionDeclaration --- .../src/ast/AstExpressionConverter.ts | 28 ++++++++++++++++++- .../src/ast/AstExpressionFactory.ts | 27 ++++++++++++++++-- .../ts-model-proto/src/Declarations.proto | 14 +++++++++- .../ElementAccessExpressionDeclaration.kt | 8 ++++++ .../PropertyAccessExpressionDeclaration.kt | 9 ++++++ .../dukat/tsmodel/factory/convertProtobuf.kt | 18 ++++++++++++ 6 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/ElementAccessExpressionDeclaration.kt create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/PropertyAccessExpressionDeclaration.kt diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index 3d012e2b8..18b53676b 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -1,5 +1,5 @@ import * as ts from "typescript-services-api"; -import {Expression, NameEntity} from "./ast"; +import {Expression, IdentifierEntity, NameEntity} from "./ast"; import {AstExpressionFactory} from "./AstExpressionFactory"; export class AstExpressionConverter { @@ -11,6 +11,14 @@ export class AstExpressionConverter { return AstExpressionFactory.createUnaryExpressionDeclarationAsExpression(operand, operator, isPrefix); } + static createPropertyAccessExpression(expression: Expression, name: IdentifierEntity) { + return AstExpressionFactory.createPropertyAccessExpressionDeclarationAsExpression(expression, name); + } + + static createElementAccessExpression(expression: Expression, argumentExpression: Expression) { + return AstExpressionFactory.createElementAccessExpressionDeclarationAsExpression(expression, argumentExpression); + } + static createNameExpression(name: NameEntity): Expression { return AstExpressionFactory.createNameExpressionDeclarationAsExpression(name) } @@ -64,6 +72,20 @@ export class AstExpressionConverter { ) } + static convertPropertyAccessExpression(expression: ts.PropertyAccessExpression): Expression { + return this.createPropertyAccessExpression( + this.convertExpression(expression.expression), + AstExpressionFactory.createIdentifier(expression.name.getText()) + ) + } + + static convertElementAccessExpression(expression: ts.ElementAccessExpression): Expression { + return this.createElementAccessExpression( + this.convertExpression(expression.expression), + this.convertExpression(expression.argumentExpression) + ) + } + static convertNameExpression(name: ts.EntityName): Expression { return this.createNameExpression( this.convertEntityName(name) @@ -137,6 +159,10 @@ export class AstExpressionConverter { return this.convertPrefixUnaryExpression(expression) } else if (ts.isPostfixUnaryExpression(expression)) { return this.convertPostfixUnaryExpression(expression) + } else if (ts.isPropertyAccessExpression(expression)) { + return this.convertPropertyAccessExpression(expression) + } else if (ts.isElementAccessExpression(expression)) { + return this.convertElementAccessExpression(expression) } else if (ts.isIdentifier(expression) || ts.isQualifiedName(expression)) { return this.convertNameExpression(expression); } else if (ts.isLiteralExpression(expression)) { diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index 78af83f5f..db4a517d7 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -27,6 +27,26 @@ export class AstExpressionFactory { return expression; } + static createPropertyAccessExpressionDeclarationAsExpression(expression: Expression, name: IdentifierEntity): Expression { + let propertyAccessExpression = new declarations.PropertyAccessExpressionDeclarationProto(); + propertyAccessExpression.setExpression(expression); + propertyAccessExpression.setName(name); + + let expressionProto = new declarations.ExpressionDeclarationProto(); + expressionProto.setPropertyaccessexpression(propertyAccessExpression); + return expressionProto; + } + + static createElementAccessExpressionDeclarationAsExpression(expression: Expression, argumentExpression: Expression): Expression { + let elementAccessExpression = new declarations.ElementAccessExpressionDeclarationProto(); + elementAccessExpression.setExpression(expression); + elementAccessExpression.setArgumentexpression(argumentExpression); + + let expressionProto = new declarations.ExpressionDeclarationProto(); + expressionProto.setElementaccessexpression(elementAccessExpression); + return expressionProto; + } + static createQualifierAsNameEntity(left: NameEntity, right: IdentifierEntity): NameEntity { let qualifier = new declarations.QualifierEntityProto(); qualifier.setLeft(left); @@ -37,12 +57,15 @@ export class AstExpressionFactory { return nameEntity; } - static createIdentifierAsNameEntity(value: string): NameEntity { + static createIdentifier(value: string): IdentifierEntity { let identifierProto = new declarations.IdentifierEntityProto(); identifierProto.setValue(value); + return identifierProto; + } + static createIdentifierAsNameEntity(value: string): NameEntity { let nameEntity = new declarations.NameEntityProto(); - nameEntity.setIdentifier(identifierProto); + nameEntity.setIdentifier(this.createIdentifier(value)); return nameEntity; } diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 7bbba9e5d..89106c44b 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -217,6 +217,16 @@ message UnaryExpressionDeclarationProto { bool isPrefix = 3; } +message PropertyAccessExpressionDeclarationProto { + ExpressionDeclarationProto expression = 1; + IdentifierEntityProto name = 2; +} + +message ElementAccessExpressionDeclarationProto { + ExpressionDeclarationProto expression = 1; + ExpressionDeclarationProto argumentExpression = 2; +} + message UnknownExpressionDeclarationProto { string meta = 1; } @@ -227,7 +237,9 @@ message ExpressionDeclarationProto { UnaryExpressionDeclarationProto unaryExpression = 2; NameExpressionDeclarationProto nameExpression = 3; LiteralExpressionDeclarationProto literalExpression = 4; - UnknownExpressionDeclarationProto unknownExpression = 5; + PropertyAccessExpressionDeclarationProto propertyAccessExpression = 5; + ElementAccessExpressionDeclarationProto elementAccessExpression = 6; + UnknownExpressionDeclarationProto unknownExpression = 7; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/ElementAccessExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/ElementAccessExpressionDeclaration.kt new file mode 100644 index 000000000..4f47e9c53 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/ElementAccessExpressionDeclaration.kt @@ -0,0 +1,8 @@ +package org.jetbrains.dukat.tsmodel.expression + +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +class ElementAccessExpressionDeclaration( + val expression: ExpressionDeclaration, + val argumentExpression: ExpressionDeclaration +) : ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/PropertyAccessExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/PropertyAccessExpressionDeclaration.kt new file mode 100644 index 000000000..c4d387dc2 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/PropertyAccessExpressionDeclaration.kt @@ -0,0 +1,9 @@ +package org.jetbrains.dukat.tsmodel.expression + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +data class PropertyAccessExpressionDeclaration( + val expression: ExpressionDeclaration, + val name: IdentifierEntity +) : ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 962e76d2e..8d974b9dc 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -36,6 +36,8 @@ import org.jetbrains.dukat.tsmodel.TypeAliasDeclaration import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.ElementAccessExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnknownExpressionDeclaration @@ -383,6 +385,20 @@ fun Declarations.LiteralExpressionDeclarationProto.convert() : LiteralExpression } } +fun Declarations.PropertyAccessExpressionDeclarationProto.convert() : PropertyAccessExpressionDeclaration { + return PropertyAccessExpressionDeclaration( + expression = expression.convert(), + name = name.convert() + ) +} + +fun Declarations.ElementAccessExpressionDeclarationProto.convert() : ElementAccessExpressionDeclaration { + return ElementAccessExpressionDeclaration( + expression = expression.convert(), + argumentExpression = argumentExpression.convert() + ) +} + fun Declarations.UnknownExpressionDeclarationProto.convert() : UnknownExpressionDeclaration { return UnknownExpressionDeclaration( meta = meta @@ -395,6 +411,8 @@ fun Declarations.ExpressionDeclarationProto.convert() : ExpressionDeclaration { hasUnaryExpression() -> unaryExpression.convert() hasNameExpression() -> nameExpression.convert() hasLiteralExpression() -> literalExpression.convert() + hasPropertyAccessExpression() -> propertyAccessExpression.convert() + hasElementAccessExpression() -> elementAccessExpression.convert() hasUnknownExpression() -> unknownExpression.convert() else -> throw Exception("unknown expression: ${this}") } From aac8bb0bba6bdf53a533709ac2fd68ed71fbf29c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2019 14:43:32 +0100 Subject: [PATCH 034/172] Allow references in functions, to outside scope --- javascript/js-interpretation/build.gradle | 9 -- .../dukat/js/interpretation/Scope.kt | 88 ----------- javascript/js-type-analysis/build.gradle | 1 - .../analysis}/expression.kt | 50 +++--- .../dukat/js/type/analysis/introduceTypes.kt | 148 ++++++++++++++++++ .../dukat/js/type/constraint/Constraint.kt | 7 + .../container/ConstraintContainer.kt | 35 +++++ .../property_owner/PropertyOwner.kt | 73 +++++++++ .../type/constraint/property_owner/Scope.kt | 22 +++ .../resolution/constraintToDeclaration.kt | 133 ++++++++++++++++ .../js/type/constraint/resolution/uid.kt | 7 + .../resolved/BigIntTypeConstraint.kt | 3 + .../resolved/BooleanTypeConstraint.kt | 3 + .../constraint/resolved/NoTypeConstraint.kt | 3 + .../resolved/NumberTypeConstraint.kt | 3 + .../constraint/resolved/ResolvedConstraint.kt | 8 + .../resolved/StringTypeConstraint.kt | 3 + .../constraint/unresolved/ClassConstraint.kt | 34 ++++ .../unresolved/FunctionConstraint.kt | 34 ++++ .../constraint/unresolved/ObjectConstraint.kt | 47 ++++++ .../unresolved/ReferenceConstraint.kt | 13 ++ .../type/export_resolution/ExportResolver.kt | 8 + .../GeneralExportResolver.kt | 14 ++ .../js/{type_analysis => type}/type/types.kt | 10 +- .../js/type_analysis/constraint/Constraint.kt | 3 - .../container/ConstraintContainer.kt | 49 ------ .../container/ReturnConstraintContainer.kt | 21 --- .../resolved/BigIntTypeConstraint.kt | 3 - .../resolved/BooleanTypeConstraint.kt | 3 - .../constraint/resolved/NoTypeConstraint.kt | 3 - .../resolved/NumberTypeConstraint.kt | 3 - .../resolved/RegExTypeConstraint.kt | 3 - .../constraint/resolved/ResolvedConstraint.kt | 5 - .../resolved/StringTypeConstraint.kt | 3 - .../jetbrains/dukat/js/type_analysis/types.kt | 113 ------------- settings.gradle | 2 - 36 files changed, 628 insertions(+), 339 deletions(-) delete mode 100644 javascript/js-interpretation/build.gradle delete mode 100644 javascript/js-interpretation/src/org/jetbrains/dukat/js/interpretation/Scope.kt rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/{type_analysis => type/analysis}/expression.kt (58%) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/container/ConstraintContainer.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/PropertyOwner.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/Scope.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/uid.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BigIntTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BooleanTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NoTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NumberTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/ResolvedConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/StringTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ClassConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/FunctionConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ObjectConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ReferenceConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/{type_analysis => type}/type/types.kt (73%) delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/Constraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BigIntTypeConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BooleanTypeConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NoTypeConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NumberTypeConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/RegExTypeConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/StringTypeConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt diff --git a/javascript/js-interpretation/build.gradle b/javascript/js-interpretation/build.gradle deleted file mode 100644 index b092ebeb5..000000000 --- a/javascript/js-interpretation/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -plugins { - id 'kotlin' -} - -dependencies { - implementation(project(":ast-common")) - implementation(project(":panic")) - implementation(project(":ts-model")) -} \ No newline at end of file diff --git a/javascript/js-interpretation/src/org/jetbrains/dukat/js/interpretation/Scope.kt b/javascript/js-interpretation/src/org/jetbrains/dukat/js/interpretation/Scope.kt deleted file mode 100644 index 64c0de62f..000000000 --- a/javascript/js-interpretation/src/org/jetbrains/dukat/js/interpretation/Scope.kt +++ /dev/null @@ -1,88 +0,0 @@ -package org.jetbrains.dukat.js.interpretation - -import org.jetbrains.dukat.panic.raiseConcern -import org.jetbrains.dukat.tsmodel.ExpressionDeclaration -import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration -import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration -import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration -import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration -import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDeclaration -import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration - - -/** - * Models variable behaviour in javascript execution. - * This includes variable access in nested scopes. - * - * @param T Type of data stored for the variables. - * @property parent Parent scope of this scope. - */ -class Scope( - private val parent: Scope? = null -) { - private val scopeData = mutableMapOf() - - operator fun set(name: String, data: T?) { - scopeData[name] = data - } - - operator fun set(identifierExpression: IdentifierExpressionDeclaration, data: T?) { - this[identifierExpression.identifier.value] = data - } - - operator fun set(expression: ExpressionDeclaration, data: T?) { - return when (expression) { - is IdentifierExpressionDeclaration -> this[expression] = data - else -> raiseConcern("Cannot set variable described by expression of type <${expression::class}>") { } - } - } - - - fun assign(name: String, data: T?) { - if (scopeData.contains(name) || parent == null) { - scopeData[name] = data - } else { - parent.assign(name, data) - } - } - - fun assign(identifierExpression: IdentifierExpressionDeclaration, data: T?) { - this.assign(identifierExpression.identifier.value, data) - } - - - fun getProperty(name: String) : T? { - return scopeData[name] ?: raiseConcern("Trying to access un-set property <$name>") { null } - } - - fun getProperty(identifierExpression: IdentifierExpressionDeclaration) : T? { - return this.getProperty(identifierExpression.identifier.value) - } - - fun getProperty(identifier: LiteralExpressionDeclaration) : T? { - return when (identifier) { - is StringLiteralExpressionDeclaration -> this.getProperty(identifier.value) - is NumericLiteralExpressionDeclaration -> this.getProperty(identifier.value) - is BigIntLiteralExpressionDeclaration -> this.getProperty(identifier.value) - is BooleanLiteralExpressionDeclaration -> this.getProperty(identifier.value.toString()) - else -> raiseConcern("Cannot access property of scope using literal identifier of type <${identifier::class}>") { null } - } - } - - - operator fun get(name: String) : T? { - return scopeData[name] ?: parent?.get(name) ?: raiseConcern("Trying to get un-set variable '$name'") { null } - } - - operator fun get(identifierExpression: IdentifierExpressionDeclaration) : T? { - return this[identifierExpression.identifier.value] - } - - operator fun get(expression: ExpressionDeclaration): T? { - return when (expression) { - is IdentifierExpressionDeclaration -> this[expression] - else -> raiseConcern("Cannot get variable described by expression of type <${expression::class}>") { null } - } - } - -} diff --git a/javascript/js-type-analysis/build.gradle b/javascript/js-type-analysis/build.gradle index 72b20ee23..b092ebeb5 100644 --- a/javascript/js-type-analysis/build.gradle +++ b/javascript/js-type-analysis/build.gradle @@ -4,7 +4,6 @@ plugins { dependencies { implementation(project(":ast-common")) - implementation(project(":js-interpretation")) implementation(project(":panic")) implementation(project(":ts-model")) } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt similarity index 58% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 784ef0ead..5944c0bf4 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -1,37 +1,36 @@ -package org.jetbrains.dukat.js.type_analysis +package org.jetbrains.dukat.js.type.analysis -import org.jetbrains.dukat.js.interpretation.Scope -import org.jetbrains.dukat.js.type_analysis.constraint.container.ConstraintContainer -import org.jetbrains.dukat.js.type_analysis.constraint.resolved.BigIntTypeConstraint -import org.jetbrains.dukat.js.type_analysis.constraint.resolved.BooleanTypeConstraint -import org.jetbrains.dukat.js.type_analysis.constraint.resolved.NoTypeConstraint -import org.jetbrains.dukat.js.type_analysis.constraint.resolved.NumberTypeConstraint -import org.jetbrains.dukat.js.type_analysis.constraint.resolved.RegExTypeConstraint -import org.jetbrains.dukat.js.type_analysis.constraint.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type.constraint.unresolved.ReferenceConstraint +import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.constraint.resolved.BigIntTypeConstraint +import org.jetbrains.dukat.js.type.constraint.resolved.BooleanTypeConstraint +import org.jetbrains.dukat.js.type.constraint.resolved.NoTypeConstraint +import org.jetbrains.dukat.js.type.constraint.resolved.NumberTypeConstraint +import org.jetbrains.dukat.js.type.constraint.resolved.StringTypeConstraint import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration -import org.jetbrains.dukat.tsmodel.expression.IdentifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDeclaration -import org.jetbrains.dukat.tsmodel.expression.literal.RegExLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration -fun BinaryExpressionDeclaration.calculateConstraints(scope: Scope) : ConstraintContainer { - val rightConstraints = right.calculateConstraints(scope) - left.calculateConstraints(scope) +fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { + val rightConstraints = right.calculateConstraints(owner) + val leftConstraints = left.calculateConstraints(owner) return when (operator) { "=" -> { - scope[left] = rightConstraints + owner[left] = rightConstraints rightConstraints } "-", "*", "/", "**", "%", "++", "--", "-=", "*=", "/=", "%=", "**=" -> { - scope[right]?.plusAssign(NumberTypeConstraint) - scope[left]?.plusAssign(NumberTypeConstraint) + rightConstraints += NumberTypeConstraint + leftConstraints += NumberTypeConstraint ConstraintContainer(NumberTypeConstraint) } "&", "|", "^", "<<", ">>" -> { @@ -46,17 +45,19 @@ fun BinaryExpressionDeclaration.calculateConstraints(scope: Scope) : ConstraintContainer { +fun UnaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { + val operandConstraints = operand.calculateConstraints(owner) + return when (operator) { "--", "++", "~" -> { - scope[operand]?.plusAssign(NumberTypeConstraint) + operandConstraints += NumberTypeConstraint ConstraintContainer(NumberTypeConstraint) } "-", "+" -> { ConstraintContainer(NumberTypeConstraint) } "!" -> { - scope[operand]?.plusAssign(BooleanTypeConstraint) + operandConstraints += BooleanTypeConstraint ConstraintContainer(BooleanTypeConstraint) } else -> { @@ -71,16 +72,15 @@ fun LiteralExpressionDeclaration.calculateConstraints() : ConstraintContainer { is NumericLiteralExpressionDeclaration -> ConstraintContainer(NumberTypeConstraint) is BigIntLiteralExpressionDeclaration -> ConstraintContainer(BigIntTypeConstraint) is BooleanLiteralExpressionDeclaration -> ConstraintContainer(BooleanTypeConstraint) - is RegExLiteralExpressionDeclaration -> ConstraintContainer(RegExTypeConstraint) else -> raiseConcern("Unexpected literal expression type <${this::class}>") { ConstraintContainer(NoTypeConstraint) } } } -fun ExpressionDeclaration?.calculateConstraints(scope: Scope) : ConstraintContainer { +fun ExpressionDeclaration?.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { return when (this) { - is IdentifierExpressionDeclaration -> scope[this] ?: ConstraintContainer(NoTypeConstraint) - is BinaryExpressionDeclaration -> this.calculateConstraints(scope) - is UnaryExpressionDeclaration -> this.calculateConstraints(scope) + is IdentifierExpressionDeclaration -> owner[this] ?: ConstraintContainer(ReferenceConstraint(this.identifier)) + is BinaryExpressionDeclaration -> this.calculateConstraints(owner) + is UnaryExpressionDeclaration -> this.calculateConstraints(owner) is LiteralExpressionDeclaration -> this.calculateConstraints() null -> ConstraintContainer() else -> ConstraintContainer(NoTypeConstraint) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt new file mode 100644 index 000000000..705743143 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -0,0 +1,148 @@ +package org.jetbrains.dukat.js.type.analysis + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.js.type.constraint.unresolved.ClassConstraint +import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer +import org.jetbrains.dukat.js.type.constraint.unresolved.FunctionConstraint +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.constraint.property_owner.Scope +import org.jetbrains.dukat.js.type.export_resolution.GeneralExportResolver +import org.jetbrains.dukat.js.type.export_resolution.ExportResolver +import org.jetbrains.dukat.panic.raiseConcern +import org.jetbrains.dukat.tsmodel.BlockDeclaration +import org.jetbrains.dukat.tsmodel.ClassDeclaration +import org.jetbrains.dukat.tsmodel.ModuleDeclaration +import org.jetbrains.dukat.tsmodel.SourceFileDeclaration +import org.jetbrains.dukat.tsmodel.SourceSetDeclaration +import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration +import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.InterfaceDeclaration +import org.jetbrains.dukat.tsmodel.MemberDeclaration +import org.jetbrains.dukat.tsmodel.ModifierDeclaration +import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration +import org.jetbrains.dukat.tsmodel.TopLevelDeclaration +import org.jetbrains.dukat.tsmodel.VariableDeclaration + +fun FunctionDeclaration.addTo(owner: PropertyOwner) { + if (this.body != null) { + val functionScope = Scope() + + val parameterConstraintContainers = MutableList(parameters.size) { i -> + // Store constraints of parameters in scope, + // and in parameter list (in case the variable is replaced) + val parameterConstraintContainer = ConstraintContainer() + functionScope[parameters[i].name] = parameterConstraintContainer + parameters[i].name to parameterConstraintContainer + } + + val returnTypeConstraints = body!!.calculateConstraints(functionScope) + + owner[name] = ConstraintContainer(FunctionConstraint( + returnConstraints = returnTypeConstraints, + parameterConstraints = parameterConstraintContainers + )) + } +} + +/*fun ConstructorDeclaration.addTo(owner: PropertyOwner) { + // TODO add body to constructor in AST and process it like a function +} + +fun InterfaceDeclaration.addTo(owner: PropertyOwner) { + val scope = Scope() + + for(member in members) { + member.calculateConstraints(scope) + } + + //owner[name] = scope +}*/ + +fun MemberDeclaration.addTo(owner: PropertyOwner) { + when (this) { + is FunctionDeclaration -> this.addTo(owner) + else -> raiseConcern("Unexpected member entity type <${this::class}>") { this } + } +} + +fun MemberDeclaration.addToClass(owner: ClassConstraint) { + when (this) { + is FunctionDeclaration -> if (this.modifiers.contains(ModifierDeclaration.STATIC_KEYWORD)) { this.addTo(owner) } else { this.addTo(owner.prototype) } + else -> raiseConcern("Unexpected member entity type <${this::class}>") { this } + } +} + +fun ClassDeclaration.addTo(owner: PropertyOwner) { + val className = name // Needed for smart cast + if(className is IdentifierEntity) { + val classConstraint = ClassConstraint() + + members.forEach { it.addToClass(classConstraint) } + + owner[className.value] = ConstraintContainer(classConstraint) + } else { + raiseConcern("Cannot convert class with name of type <${className::class}>.") { } + } +} + +fun BlockDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { + return statements.calculateConstraints(owner) +} + +fun VariableDeclaration.addTo(owner: PropertyOwner) { + owner[name] = initializer.calculateConstraints(owner) +} + +fun ExpressionStatementDeclaration.calculateConstraints(owner: PropertyOwner) { + expression.calculateConstraints(owner) +} + +fun ReturnStatementDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { + return ConstraintContainer(expression.calculateConstraints(owner)) +} + +fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer? { + var returnTypeConstraints: ConstraintContainer? = null + + when (this) { + is FunctionDeclaration -> this.addTo(owner) + is ClassDeclaration -> this.addTo(owner) + is VariableDeclaration -> this.addTo(owner) + is ExpressionStatementDeclaration -> this.calculateConstraints(owner) + is BlockDeclaration -> returnTypeConstraints = this.calculateConstraints(owner) + is ReturnStatementDeclaration -> returnTypeConstraints = this.calculateConstraints(owner) + is InterfaceDeclaration, + is ModuleDeclaration -> { } + else -> raiseConcern("Unexpected top level entity type <${this::class}>") { } + } + + return returnTypeConstraints +} + +fun List.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { + var returnTypeConstraints = ConstraintContainer() + + for(statement in this) { + val statementReturnTypeConstraints = statement.calculateConstraints(owner) + + if(statementReturnTypeConstraints != null) { + // This should only happen once per code block + returnTypeConstraints = statementReturnTypeConstraints + } + } + + return returnTypeConstraints +} + +fun ModuleDeclaration.calculateConstraints(owner: PropertyOwner) = declarations.calculateConstraints(owner) + +fun ModuleDeclaration.introduceTypes(exportResolver: ExportResolver) : ModuleDeclaration { + val scope = Scope() + calculateConstraints(scope) + val declarations = exportResolver.resolve(scope) + return copy(declarations = declarations) +} + +fun SourceFileDeclaration.introduceTypes(exportResolver: ExportResolver) = copy(root = root.introduceTypes(exportResolver)) + +fun SourceSetDeclaration.introduceTypes(exportResolver: ExportResolver = GeneralExportResolver()) = copy(sources = sources.map { it.introduceTypes(exportResolver) }) \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt new file mode 100644 index 000000000..aace656be --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.js.type.constraint + +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner + +interface Constraint { + fun resolve(owner: PropertyOwner) : Constraint +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/container/ConstraintContainer.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/container/ConstraintContainer.kt new file mode 100644 index 000000000..4cb6b8a5e --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/container/ConstraintContainer.kt @@ -0,0 +1,35 @@ +package org.jetbrains.dukat.js.type.constraint.container + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner + +class ConstraintContainer(protected val constraints: MutableSet) : Constraint { + constructor(vararg constraints: Constraint) : this(mutableSetOf(*constraints)) + constructor(constraints: List) : this(constraints.toMutableSet()) + + operator fun plusAssign(constraint: Constraint) { + constraints += constraint + } + + operator fun plusAssign(newConstraints: Collection) { + constraints.addAll(newConstraints) + } + + fun copy() : ConstraintContainer { + return ConstraintContainer(constraints) + } + + fun getFlatConstraints() : List { + return constraints.flatMap { constraint -> + if(constraint is ConstraintContainer) { + constraint.getFlatConstraints() + } else { + listOf(constraint) + } + } + } + + override fun resolve(owner: PropertyOwner): Constraint { + return ConstraintContainer(getFlatConstraints().map { it.resolve(owner) }) + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/PropertyOwner.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/PropertyOwner.kt new file mode 100644 index 000000000..2c96ac496 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/PropertyOwner.kt @@ -0,0 +1,73 @@ +package org.jetbrains.dukat.js.type.constraint.property_owner + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer +import org.jetbrains.dukat.panic.raiseConcern +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration + +interface PropertyOwner { + val propertyNames: Set + + operator fun set(name: String, data: ConstraintContainer) + + operator fun set(identifier: IdentifierEntity, data: ConstraintContainer) { + this[identifier.value] = data + } + + operator fun set(identifierExpression: IdentifierExpressionDeclaration, data: ConstraintContainer) { + this[identifierExpression.identifier] = data + } + + //operator fun set(propertyAccessExpression: PropertyAccessExpressionDeclaration, data: ConstraintContainer) + + operator fun set(expression: ExpressionDeclaration, data: ConstraintContainer) { + when (expression) { + is IdentifierExpressionDeclaration -> this[expression] = data + //is PropertyAccessExpressionDeclaration -> this[expression] = data + else -> raiseConcern("Cannot set variable described by expression of type <${expression::class}>") { } + } + } + + + fun has(name: String) : Boolean + + fun has(identifier: IdentifierEntity) : Boolean { + return has(identifier.value) + } + + fun has(identifierExpression: IdentifierExpressionDeclaration) : Boolean { + return has(identifierExpression.identifier) + } + + //fun has(propertyAccessExpression: PropertyAccessExpressionDeclaration) : Boolean + + fun has(expression: ExpressionDeclaration) : Boolean { + return when (expression) { + is IdentifierExpressionDeclaration -> has(expression) + //is PropertyAccessExpressionDeclaration -> has(expression) + else -> raiseConcern("Cannot get variable described by expression of type <${expression::class}>") { false } + } + } + + + operator fun get(name: String) : ConstraintContainer? + + operator fun get(identifier: IdentifierEntity) : ConstraintContainer? { + return this[identifier.value] + } + + operator fun get(identifierExpression: IdentifierExpressionDeclaration) : ConstraintContainer? { + return this[identifierExpression.identifier] + } + + //operator fun get(propertyAccessExpression: PropertyAccessExpressionDeclaration) : ConstraintContainer? + + operator fun get(expression: ExpressionDeclaration) : ConstraintContainer? { + return when (expression) { + is IdentifierExpressionDeclaration -> this[expression] + //is PropertyAccessExpressionDeclaration -> this[expression] + else -> raiseConcern("Cannot get variable described by expression of type <${expression::class}>") { null } + } + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/Scope.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/Scope.kt new file mode 100644 index 000000000..f010fa5aa --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/Scope.kt @@ -0,0 +1,22 @@ +package org.jetbrains.dukat.js.type.constraint.property_owner + +import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer + +class Scope : PropertyOwner { + override val propertyNames: Set + get() = properties.keys + + private val properties = LinkedHashMap() + + override fun set(name: String, data: ConstraintContainer) { + properties[name] = data + } + + override fun has(name: String): Boolean { + return properties.containsKey(name) + } + + override fun get(name: String): ConstraintContainer? { + return properties[name] + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt new file mode 100644 index 000000000..7c23a8f4c --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -0,0 +1,133 @@ +package org.jetbrains.dukat.js.type.constraint.resolution + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer +import org.jetbrains.dukat.js.type.constraint.resolved.BigIntTypeConstraint +import org.jetbrains.dukat.js.type.constraint.resolved.BooleanTypeConstraint +import org.jetbrains.dukat.js.type.constraint.resolved.NumberTypeConstraint +import org.jetbrains.dukat.js.type.constraint.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type.constraint.unresolved.ClassConstraint +import org.jetbrains.dukat.js.type.constraint.unresolved.FunctionConstraint +import org.jetbrains.dukat.js.type.type.anyNullableType +import org.jetbrains.dukat.js.type.type.booleanType +import org.jetbrains.dukat.js.type.type.numberType +import org.jetbrains.dukat.js.type.type.stringType +import org.jetbrains.dukat.js.type.type.unitType +import org.jetbrains.dukat.panic.raiseConcern +import org.jetbrains.dukat.tsmodel.ClassDeclaration +import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.MemberDeclaration +import org.jetbrains.dukat.tsmodel.ModifierDeclaration +import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.TopLevelDeclaration +import org.jetbrains.dukat.tsmodel.VariableDeclaration +import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration +import org.jetbrains.dukat.tsmodel.types.TypeDeclaration + +val EXPORT_MODIFIERS = listOf(ModifierDeclaration.EXPORT_KEYWORD) +val STATIC_MODIFIERS = listOf(ModifierDeclaration.STATIC_KEYWORD) + +fun getVariableDeclaration(name: String, type: ParameterValueDeclaration) = VariableDeclaration( + name = name, + type = type, + modifiers = EXPORT_MODIFIERS, + initializer = null, + uid = getUID() +) + +fun ConstraintContainer.toParameterDeclaration(name: String) = ParameterDeclaration( + name = name, + type = this.toType(), + initializer = null, + vararg = false, + optional = false +) + +fun FunctionConstraint.toDeclaration(name: String) = FunctionDeclaration( + name = name, + parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, + type = returnConstraints.toType(unitType), + typeParameters = emptyList(), + modifiers = EXPORT_MODIFIERS, + body = null, + uid = getUID() +) + +fun ConstraintContainer.toMemberDeclaration(name: String, isStatic: Boolean) : MemberDeclaration? { + return when (val declaration = toDeclaration(name)) { + is FunctionDeclaration -> return declaration.copy(modifiers = if (isStatic) STATIC_MODIFIERS else emptyList()) + else -> raiseConcern("Cannot convert declaration of type <${declaration?.let {declaration::class} ?: "null"} to member.>") { null } + } +} + +fun ClassConstraint.toDeclaration(name: String) : ClassDeclaration { + val members = mutableListOf() + + members.addAll( + prototype.propertyNames.mapNotNull { memberName -> + prototype[memberName]?.toMemberDeclaration(name = memberName, isStatic = false) + } + ) + + members.addAll( + propertyNames.mapNotNull { memberName -> + this[memberName]?.toMemberDeclaration(name = memberName, isStatic = true) + } + ) + + return ClassDeclaration( + name = IdentifierEntity(name), + members = members, + typeParameters = emptyList(), + parentEntities = emptyList(), //TODO support inheritance, + modifiers = EXPORT_MODIFIERS, + uid = getUID() + ) +} + +fun List.toType() : TypeDeclaration? { + return when { + this.contains(NumberTypeConstraint) -> numberType + this.contains(BigIntTypeConstraint) -> numberType + this.contains(BooleanTypeConstraint) -> booleanType + this.contains(StringTypeConstraint) -> stringType + this.isEmpty() -> null + else -> anyNullableType + } +} + +fun ConstraintContainer.toType(defaultType: TypeDeclaration = anyNullableType) : TypeDeclaration { + val flatConstraints = getFlatConstraints() + return flatConstraints.toType() ?: defaultType +} + +fun ConstraintContainer.toDeclaration(name: String) : TopLevelDeclaration? { + var declaration: TopLevelDeclaration? = null + + val flatConstraints = getFlatConstraints() + + flatConstraints.forEach { + when (it) { + is ClassConstraint -> declaration = it.toDeclaration(name) + is FunctionConstraint -> declaration = it.toDeclaration(name) + } + } + + if(declaration == null) { + val type = flatConstraints.toType() + + if(type != null) { + declaration = getVariableDeclaration(name, type) + } + } + + return declaration +} + +fun Constraint.toDeclaration(name: String) : TopLevelDeclaration? { + return when (this) { + is ConstraintContainer -> this.toDeclaration(name) + else -> raiseConcern("Export cannot be defined by constraint directly.") { null } + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/uid.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/uid.kt new file mode 100644 index 000000000..a702fe10b --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/uid.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.js.type.constraint.resolution + +private var uid = 0; + +internal fun getUID() : String { + return uid++.toString() +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BigIntTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BigIntTypeConstraint.kt new file mode 100644 index 000000000..8680153b4 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BigIntTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.resolved + +object BigIntTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BooleanTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BooleanTypeConstraint.kt new file mode 100644 index 000000000..ff0759d83 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BooleanTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.resolved + +object BooleanTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NoTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NoTypeConstraint.kt new file mode 100644 index 000000000..cd5dd4622 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NoTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.resolved + +object NoTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NumberTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NumberTypeConstraint.kt new file mode 100644 index 000000000..8296617b8 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NumberTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.resolved + +object NumberTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/ResolvedConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/ResolvedConstraint.kt new file mode 100644 index 000000000..6a183cdf2 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/ResolvedConstraint.kt @@ -0,0 +1,8 @@ +package org.jetbrains.dukat.js.type.constraint.resolved + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner + +interface ResolvedConstraint : Constraint { + override fun resolve(owner: PropertyOwner) = this +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/StringTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/StringTypeConstraint.kt new file mode 100644 index 000000000..c118a240d --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/StringTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.resolved + +object StringTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ClassConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ClassConstraint.kt new file mode 100644 index 000000000..0ef23cf84 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ClassConstraint.kt @@ -0,0 +1,34 @@ +package org.jetbrains.dukat.js.type.constraint.unresolved + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner + +class ClassConstraint(val prototype: ObjectConstraint = ObjectConstraint()) : PropertyOwner, Constraint { + override val propertyNames: Set + get() = staticMembers.keys + + private val staticMembers = LinkedHashMap() + + override fun set(name: String, data: ConstraintContainer) { + staticMembers[name] = data + } + + override fun has(name: String): Boolean { + return staticMembers.containsKey(name) + } + + override fun get(name: String): ConstraintContainer? { + return staticMembers[name] + } + + override fun resolve(owner: PropertyOwner): Constraint { + val resolvedConstraint = ClassConstraint(prototype.resolve(owner) as ObjectConstraint) + + propertyNames.forEach { + resolvedConstraint[it] = ConstraintContainer(this[it]!!.resolve(owner)) + } + + return resolvedConstraint + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/FunctionConstraint.kt new file mode 100644 index 000000000..50cde0cc9 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/FunctionConstraint.kt @@ -0,0 +1,34 @@ +package org.jetbrains.dukat.js.type.constraint.unresolved + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner + +class FunctionConstraint( + val returnConstraints: ConstraintContainer, + val parameterConstraints: List> +) : PropertyOwner, Constraint { + override val propertyNames: Set + get() = properties.keys + + private val properties = LinkedHashMap() + + override fun set(name: String, data: ConstraintContainer) { + properties[name] = data + } + + override fun has(name: String): Boolean { + return properties.containsKey(name) + } + + override fun get(name: String): ConstraintContainer? { + return properties[name] + } + + override fun resolve(owner: PropertyOwner): Constraint { + return FunctionConstraint( + ConstraintContainer(returnConstraints.resolve(owner)), + parameterConstraints.map { (name, constraint) -> name to ConstraintContainer(constraint.resolve(owner)) } + ) + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ObjectConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ObjectConstraint.kt new file mode 100644 index 000000000..d3344ea0c --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ObjectConstraint.kt @@ -0,0 +1,47 @@ +package org.jetbrains.dukat.js.type.constraint.unresolved + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner + +class ObjectConstraint( + private val instantiatedClass: ClassConstraint? = null +) : PropertyOwner, Constraint { + override val propertyNames: Set + get() { + val names = mutableSetOf() + names.addAll(properties.keys) + instantiatedClass?.let { + names.addAll(it.prototype.propertyNames) + } + return names + } + + private val properties = LinkedHashMap() + + override fun set(name: String, data: ConstraintContainer) { + properties[name] = data + } + + override fun has(name: String): Boolean { + return properties.containsKey(name) || instantiatedClass?.prototype?.has(name) == true + } + + override fun get(name: String): ConstraintContainer? { + return when { + properties.containsKey(name) -> properties[name] + instantiatedClass?.prototype?.has(name) == true -> instantiatedClass.prototype[name] + else -> null + } + } + + override fun resolve(owner: PropertyOwner): Constraint { + val resolvedConstraint = ObjectConstraint() + + propertyNames.forEach { + resolvedConstraint[it] = ConstraintContainer(this[it]!!.resolve(owner)) + } + + return resolvedConstraint + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ReferenceConstraint.kt new file mode 100644 index 000000000..7b77d5434 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ReferenceConstraint.kt @@ -0,0 +1,13 @@ +package org.jetbrains.dukat.js.type.constraint.unresolved + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner + +data class ReferenceConstraint( + val identifier: IdentifierEntity +) : Constraint { + override fun resolve(owner: PropertyOwner): Constraint { + return owner[identifier] ?: this + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt new file mode 100644 index 000000000..87ce776b2 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt @@ -0,0 +1,8 @@ +package org.jetbrains.dukat.js.type.export_resolution + +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner +import org.jetbrains.dukat.tsmodel.TopLevelDeclaration + +interface ExportResolver { + fun resolve(owner: PropertyOwner) : List +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt new file mode 100644 index 000000000..17f1177f5 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt @@ -0,0 +1,14 @@ +package org.jetbrains.dukat.js.type.export_resolution + +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.constraint.resolution.toDeclaration +import org.jetbrains.dukat.tsmodel.TopLevelDeclaration + +class GeneralExportResolver : ExportResolver { + override fun resolve(owner: PropertyOwner) : List { + return owner.propertyNames.mapNotNull { propertyName -> + val resolvedConstraint = owner[propertyName]?.resolve(owner) + resolvedConstraint?.toDeclaration(propertyName) + } + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/type/types.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/type/types.kt similarity index 73% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/type/types.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/type/types.kt index 0350b12eb..9df6e5264 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/type/types.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/type/types.kt @@ -1,4 +1,4 @@ -package org.jetbrains.dukat.js.type_analysis.type +package org.jetbrains.dukat.js.type.type import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.tsmodel.types.TypeDeclaration @@ -10,25 +10,25 @@ val unitType = TypeDeclaration( ) val anyNullableType = TypeDeclaration( - value = IdentifierEntity("Any"), + value = IdentifierEntity("any"), params = emptyList(), nullable = true ) val numberType = TypeDeclaration( - value = IdentifierEntity("Number"), + value = IdentifierEntity("number"), params = emptyList(), nullable = false ) val booleanType = TypeDeclaration( - value = IdentifierEntity("Boolean"), + value = IdentifierEntity("boolean"), params = emptyList(), nullable = false ) val stringType = TypeDeclaration( - value = IdentifierEntity("String"), + value = IdentifierEntity("string"), params = emptyList(), nullable = false ) \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/Constraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/Constraint.kt deleted file mode 100644 index 5d53965e7..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/Constraint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.js.type_analysis.constraint - -interface Constraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt deleted file mode 100644 index dc839e5a5..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ConstraintContainer.kt +++ /dev/null @@ -1,49 +0,0 @@ -package org.jetbrains.dukat.js.type_analysis.constraint.container - -import org.jetbrains.dukat.js.type_analysis.constraint.Constraint -import org.jetbrains.dukat.js.type_analysis.constraint.resolved.BigIntTypeConstraint -import org.jetbrains.dukat.js.type_analysis.constraint.resolved.BooleanTypeConstraint -import org.jetbrains.dukat.js.type_analysis.constraint.resolved.NumberTypeConstraint -import org.jetbrains.dukat.js.type_analysis.constraint.resolved.StringTypeConstraint -import org.jetbrains.dukat.js.type_analysis.type.anyNullableType -import org.jetbrains.dukat.js.type_analysis.type.booleanType -import org.jetbrains.dukat.js.type_analysis.type.numberType -import org.jetbrains.dukat.js.type_analysis.type.stringType -import org.jetbrains.dukat.tsmodel.types.TypeDeclaration - -open class ConstraintContainer(protected val constraints: MutableSet) : Constraint { - constructor(vararg params: Constraint) : this(mutableSetOf(*params)) - - open operator fun plusAssign(constraint: Constraint) { - constraints += constraint - } - - open operator fun plusAssign(newConstraints: Collection) { - constraints.addAll(newConstraints) - } - - open fun copy() : ConstraintContainer { - return ConstraintContainer(constraints) - } - - open fun getFlatConstraints() : List { - return constraints.flatMap { constraint -> - if(constraint is ConstraintContainer) { - constraint.getFlatConstraints() - } else { - listOf(constraint) - } - } - } - - open fun resolveToType() : TypeDeclaration { - val flatConstraints = getFlatConstraints() - return when { - flatConstraints.contains(NumberTypeConstraint) -> numberType - flatConstraints.contains(BigIntTypeConstraint) -> numberType - flatConstraints.contains(BooleanTypeConstraint) -> booleanType - flatConstraints.contains(StringTypeConstraint) -> stringType - else -> anyNullableType - } - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt deleted file mode 100644 index 4b20c152b..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/container/ReturnConstraintContainer.kt +++ /dev/null @@ -1,21 +0,0 @@ -package org.jetbrains.dukat.js.type_analysis.constraint.container - -import org.jetbrains.dukat.js.type_analysis.constraint.Constraint -import org.jetbrains.dukat.js.type_analysis.type.unitType -import org.jetbrains.dukat.tsmodel.types.TypeDeclaration - -class ReturnConstraintContainer(constraints: MutableSet) : ConstraintContainer(constraints) { - constructor(vararg params: Constraint) : this(mutableSetOf(*params)) - - override fun copy(): ConstraintContainer { - return ReturnConstraintContainer(constraints) - } - - override fun resolveToType(): TypeDeclaration { - return if(getFlatConstraints().isEmpty()) { - unitType - } else { - super.resolveToType() - } - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BigIntTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BigIntTypeConstraint.kt deleted file mode 100644 index c690f047c..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BigIntTypeConstraint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.js.type_analysis.constraint.resolved - -object BigIntTypeConstraint : ResolvedConstraint() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BooleanTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BooleanTypeConstraint.kt deleted file mode 100644 index ade59c337..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/BooleanTypeConstraint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.js.type_analysis.constraint.resolved - -object BooleanTypeConstraint : ResolvedConstraint() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NoTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NoTypeConstraint.kt deleted file mode 100644 index c6e86b390..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NoTypeConstraint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.js.type_analysis.constraint.resolved - -object NoTypeConstraint : ResolvedConstraint() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NumberTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NumberTypeConstraint.kt deleted file mode 100644 index 3260656bd..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/NumberTypeConstraint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.js.type_analysis.constraint.resolved - -object NumberTypeConstraint : ResolvedConstraint() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/RegExTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/RegExTypeConstraint.kt deleted file mode 100644 index 4ac473bdd..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/RegExTypeConstraint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.js.type_analysis.constraint.resolved - -object RegExTypeConstraint : ResolvedConstraint() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt deleted file mode 100644 index aac043d25..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/ResolvedConstraint.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.jetbrains.dukat.js.type_analysis.constraint.resolved - -import org.jetbrains.dukat.js.type_analysis.constraint.Constraint - -abstract class ResolvedConstraint : Constraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/StringTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/StringTypeConstraint.kt deleted file mode 100644 index dd77f6dbf..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/constraint/resolved/StringTypeConstraint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.js.type_analysis.constraint.resolved - -object StringTypeConstraint : ResolvedConstraint() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt deleted file mode 100644 index 64b8e601b..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type_analysis/types.kt +++ /dev/null @@ -1,113 +0,0 @@ -package org.jetbrains.dukat.js.type_analysis - -import org.jetbrains.dukat.js.interpretation.Scope -import org.jetbrains.dukat.js.type_analysis.constraint.container.ConstraintContainer -import org.jetbrains.dukat.js.type_analysis.constraint.container.ReturnConstraintContainer -import org.jetbrains.dukat.panic.raiseConcern -import org.jetbrains.dukat.tsmodel.BlockDeclaration -import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration -import org.jetbrains.dukat.tsmodel.ClassDeclaration -import org.jetbrains.dukat.tsmodel.ConstructorDeclaration -import org.jetbrains.dukat.tsmodel.EnumDeclaration -import org.jetbrains.dukat.tsmodel.ExportAssignmentDeclaration -import org.jetbrains.dukat.tsmodel.ModuleDeclaration -import org.jetbrains.dukat.tsmodel.SourceFileDeclaration -import org.jetbrains.dukat.tsmodel.SourceSetDeclaration -import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration -import org.jetbrains.dukat.tsmodel.FunctionDeclaration -import org.jetbrains.dukat.tsmodel.ImportEqualsDeclaration -import org.jetbrains.dukat.tsmodel.InterfaceDeclaration -import org.jetbrains.dukat.tsmodel.MemberDeclaration -import org.jetbrains.dukat.tsmodel.MethodSignatureDeclaration -import org.jetbrains.dukat.tsmodel.PropertyDeclaration -import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration -import org.jetbrains.dukat.tsmodel.TopLevelDeclaration -import org.jetbrains.dukat.tsmodel.TypeAliasDeclaration -import org.jetbrains.dukat.tsmodel.VariableDeclaration -import org.jetbrains.dukat.tsmodel.types.IndexSignatureDeclaration - -fun FunctionDeclaration.introduceTypes() : FunctionDeclaration { - if (this.body != null) { - val functionScope = Scope() - - var returnTypeConstraints = ReturnConstraintContainer() - val parameterConstraintContainers = MutableList(parameters.size) { i -> - // Store constraints of parameters in scope, - // and in parameter list (in case the variable is replaced) - val parameterConstraintContainer = ConstraintContainer() - functionScope[parameters[i].name] = parameterConstraintContainer - parameterConstraintContainer - } - - for(statement in this.body!!.statements) { - when(statement) { - is VariableDeclaration -> functionScope[statement.name] = statement.initializer.calculateConstraints(functionScope) - is ExpressionStatementDeclaration -> statement.expression.calculateConstraints(functionScope) - is ReturnStatementDeclaration -> returnTypeConstraints = ReturnConstraintContainer(statement.expression.calculateConstraints(functionScope)) - else -> raiseConcern("Cannot derive types in function with statement of type <${statement::class}>") { } - } - } - - return copy( - type = returnTypeConstraints.resolveToType(), - parameters = parameterConstraintContainers.mapIndexed { i, parameterConstraints -> - parameters[i].copy( - type = parameterConstraints.resolveToType() - ) - } - ) - } else { - return this; - } -} - -fun ConstructorDeclaration.introduceTypes() : ConstructorDeclaration { - // TODO add body to constructor in AST and process it like a function - return this -} - -fun MemberDeclaration.introduceTypes(): MemberDeclaration { - return when (this) { - is FunctionDeclaration -> this.introduceTypes() - is ConstructorDeclaration -> this.introduceTypes() - is PropertyDeclaration -> this - is IndexSignatureDeclaration -> this - is MethodSignatureDeclaration -> this - is CallSignatureDeclaration -> this - else -> raiseConcern("Unexpected member entity type <${this::class}>") { this } - } -} - -fun ClassDeclaration.introduceTypes() = copy(members = members.map { it.introduceTypes() }) - -fun InterfaceDeclaration.introduceTypes() = copy(members = members.map { it.introduceTypes() }) - -fun BlockDeclaration.introduceTypes() = copy(statements = statements.map { it.introduceTypes() }) - -fun TopLevelDeclaration.introduceTypes(): TopLevelDeclaration { - return when (this) { - is FunctionDeclaration -> this.introduceTypes() - is BlockDeclaration -> this.introduceTypes() - is ClassDeclaration -> this.introduceTypes() - is InterfaceDeclaration -> this.introduceTypes() - is ModuleDeclaration -> this.introduceTypes() - is VariableDeclaration, - is EnumDeclaration, - is ExportAssignmentDeclaration, - is ImportEqualsDeclaration, - is TypeAliasDeclaration, - is ReturnStatementDeclaration, - is ExpressionStatementDeclaration -> this - else -> raiseConcern("Unexpected top level entity type <${this::class}>") { this } - } -} - -fun ModuleDeclaration.introduceTypes(): ModuleDeclaration = copy(declarations = declarations.map { it.introduceTypes() }) - -fun SourceFileDeclaration.introduceTypes(): SourceFileDeclaration { - return if (fileName.endsWith(".d.ts")) { //TODO replace with ".js" - copy(root = root.introduceTypes()) - } else this -} - -fun SourceSetDeclaration.introduceTypes() = copy(sources = sources.map{ it.introduceTypes() }) diff --git a/settings.gradle b/settings.gradle index 713622926..f4c86a671 100644 --- a/settings.gradle +++ b/settings.gradle @@ -53,7 +53,6 @@ include 'idl-parser' include 'idl-reference-resolver' include 'interop' include 'itertools' -include 'js-interpretation' include 'js-module-statistics' include 'js-type-analysis' include 'logging' @@ -79,7 +78,6 @@ project(':idl-models').projectDir = file("$rootDir/idl/idl-models") project(':idl-parser').projectDir = file("$rootDir/idl/idl-parser") project(':idl-reference-resolver').projectDir = file("$rootDir/idl/idl-reference-resolver") -project(':js-interpretation').projectDir = file("$rootDir/javascript/js-interpretation") project(':js-module-statistics').projectDir = file("$rootDir/javascript/js-module-statistics") project(':js-type-analysis').projectDir = file("$rootDir/javascript/js-type-analysis") From b78a06dc26a242980decdfc9675b735725ea5430 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2019 15:01:22 +0100 Subject: [PATCH 035/172] Add typeof expression --- .../src/ast/AstExpressionConverter.ts | 12 ++++++++++++ .../ts-converter/src/ast/AstExpressionFactory.ts | 9 +++++++++ typescript/ts-model-proto/src/Declarations.proto | 15 ++++++++++----- .../expression/TypeOfExpressionDeclaration.kt | 7 +++++++ .../dukat/tsmodel/factory/convertProtobuf.kt | 8 ++++++++ 5 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/TypeOfExpressionDeclaration.kt diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index 18b53676b..7b138ecd8 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -11,6 +11,10 @@ export class AstExpressionConverter { return AstExpressionFactory.createUnaryExpressionDeclarationAsExpression(operand, operator, isPrefix); } + static createTypeOfExpression(expression: Expression) { + return AstExpressionFactory.createTypeOfExpressionDeclarationAsExpression(expression); + } + static createPropertyAccessExpression(expression: Expression, name: IdentifierEntity) { return AstExpressionFactory.createPropertyAccessExpressionDeclarationAsExpression(expression, name); } @@ -72,6 +76,12 @@ export class AstExpressionConverter { ) } + static convertTypeOfExpression(expression: ts.TypeOfExpression): Expression { + return this.createTypeOfExpression( + this.convertExpression(expression.expression), + ) + } + static convertPropertyAccessExpression(expression: ts.PropertyAccessExpression): Expression { return this.createPropertyAccessExpression( this.convertExpression(expression.expression), @@ -159,6 +169,8 @@ export class AstExpressionConverter { return this.convertPrefixUnaryExpression(expression) } else if (ts.isPostfixUnaryExpression(expression)) { return this.convertPostfixUnaryExpression(expression) + } else if (ts.isTypeOfExpression(expression)) { + return this.convertTypeOfExpression(expression); } else if (ts.isPropertyAccessExpression(expression)) { return this.convertPropertyAccessExpression(expression) } else if (ts.isElementAccessExpression(expression)) { diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index db4a517d7..fc0d92a74 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -27,6 +27,15 @@ export class AstExpressionFactory { return expression; } + static createTypeOfExpressionDeclarationAsExpression(expression: Expression): Expression { + let typeOfExpression = new declarations.TypeOfExpressionDeclarationProto(); + typeOfExpression.setExpression(expression); + + let expressionProto = new declarations.ExpressionDeclarationProto(); + expressionProto.setTypeofexpression(typeOfExpression); + return expressionProto; + } + static createPropertyAccessExpressionDeclarationAsExpression(expression: Expression, name: IdentifierEntity): Expression { let propertyAccessExpression = new declarations.PropertyAccessExpressionDeclarationProto(); propertyAccessExpression.setExpression(expression); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 89106c44b..4d5b6464a 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -217,6 +217,10 @@ message UnaryExpressionDeclarationProto { bool isPrefix = 3; } +message TypeOfExpressionDeclarationProto { + ExpressionDeclarationProto expression = 1; +} + message PropertyAccessExpressionDeclarationProto { ExpressionDeclarationProto expression = 1; IdentifierEntityProto name = 2; @@ -235,11 +239,12 @@ message ExpressionDeclarationProto { oneof type { BinaryExpressionDeclarationProto binaryExpression = 1; UnaryExpressionDeclarationProto unaryExpression = 2; - NameExpressionDeclarationProto nameExpression = 3; - LiteralExpressionDeclarationProto literalExpression = 4; - PropertyAccessExpressionDeclarationProto propertyAccessExpression = 5; - ElementAccessExpressionDeclarationProto elementAccessExpression = 6; - UnknownExpressionDeclarationProto unknownExpression = 7; + TypeOfExpressionDeclarationProto typeOfExpression = 3; + NameExpressionDeclarationProto nameExpression = 4; + LiteralExpressionDeclarationProto literalExpression = 5; + PropertyAccessExpressionDeclarationProto propertyAccessExpression = 6; + ElementAccessExpressionDeclarationProto elementAccessExpression = 7; + UnknownExpressionDeclarationProto unknownExpression = 8; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/TypeOfExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/TypeOfExpressionDeclaration.kt new file mode 100644 index 000000000..b0c5ed24b --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/TypeOfExpressionDeclaration.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.tsmodel.expression + +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +data class TypeOfExpressionDeclaration( + val expression: ExpressionDeclaration +) : ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 8d974b9dc..0786f6491 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -38,6 +38,7 @@ import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.ElementAccessExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.TypeOfExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnknownExpressionDeclaration @@ -360,6 +361,12 @@ fun Declarations.UnaryExpressionDeclarationProto.convert() : UnaryExpressionDecl ) } +fun Declarations.TypeOfExpressionDeclarationProto.convert(): TypeOfExpressionDeclaration { + return TypeOfExpressionDeclaration( + expression = expression.convert() + ) +} + fun Declarations.NameExpressionDeclarationProto.convert() : NameExpressionDeclaration { return when { name.hasIdentifier() -> IdentifierExpressionDeclaration(identifier = name.identifier.convert()) @@ -409,6 +416,7 @@ fun Declarations.ExpressionDeclarationProto.convert() : ExpressionDeclaration { return when { hasBinaryExpression() -> binaryExpression.convert() hasUnaryExpression() -> unaryExpression.convert() + hasTypeOfExpression() -> typeOfExpression.convert() hasNameExpression() -> nameExpression.convert() hasLiteralExpression() -> literalExpression.convert() hasPropertyAccessExpression() -> propertyAccessExpression.convert() From b587ae337d543c39266eb7a25f983525dbea1268 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2019 16:41:54 +0100 Subject: [PATCH 036/172] Support typeof expression --- .../src/org/jetbrains/dukat/js/type/analysis/expression.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 5944c0bf4..32ca63c9a 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -11,6 +11,7 @@ import org.jetbrains.dukat.js.type.constraint.resolved.StringTypeConstraint import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.TypeOfExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration @@ -66,6 +67,11 @@ fun UnaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Cons } } +fun TypeOfExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { + expression.calculateConstraints(owner) + return ConstraintContainer(StringTypeConstraint) +} + fun LiteralExpressionDeclaration.calculateConstraints() : ConstraintContainer { return when (this) { is StringLiteralExpressionDeclaration -> ConstraintContainer(StringTypeConstraint) @@ -81,6 +87,7 @@ fun ExpressionDeclaration?.calculateConstraints(owner: PropertyOwner) : Constrai is IdentifierExpressionDeclaration -> owner[this] ?: ConstraintContainer(ReferenceConstraint(this.identifier)) is BinaryExpressionDeclaration -> this.calculateConstraints(owner) is UnaryExpressionDeclaration -> this.calculateConstraints(owner) + is TypeOfExpressionDeclaration -> this.calculateConstraints(owner) is LiteralExpressionDeclaration -> this.calculateConstraints() null -> ConstraintContainer() else -> ConstraintContainer(NoTypeConstraint) From 1d97769057ff5c5d493bdbd7b5166c2a8a412194 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2019 16:43:04 +0100 Subject: [PATCH 037/172] Make type analysis from boolean operations more accurate --- .../src/org/jetbrains/dukat/js/type/analysis/expression.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 32ca63c9a..f4d4963ce 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -29,6 +29,10 @@ fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Con owner[left] = rightConstraints rightConstraints } + "&&", "||" -> { + //TODO make this branching + leftConstraints + } "-", "*", "/", "**", "%", "++", "--", "-=", "*=", "/=", "%=", "**=" -> { rightConstraints += NumberTypeConstraint leftConstraints += NumberTypeConstraint @@ -58,7 +62,6 @@ fun UnaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Cons ConstraintContainer(NumberTypeConstraint) } "!" -> { - operandConstraints += BooleanTypeConstraint ConstraintContainer(BooleanTypeConstraint) } else -> { From 58bbf2985c50044d21f1d625ebaa5101741085a0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2019 17:51:39 +0100 Subject: [PATCH 038/172] Add boolean as return type for 'in' operator --- .../src/org/jetbrains/dukat/js/type/analysis/expression.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index f4d4963ce..9e75c0997 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -41,7 +41,7 @@ fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Con "&", "|", "^", "<<", ">>" -> { ConstraintContainer(NumberTypeConstraint) } - "==", "===", "!=", "!==", ">", "<", ">=", "<=" -> { + "==", "===", "!=", "!==", ">", "<", ">=", "<=", "in" -> { ConstraintContainer(BooleanTypeConstraint) } else -> { From 06d3cbea5b20bba14fb5a9ca12e525dedc47d8bc Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2019 10:23:23 +0100 Subject: [PATCH 039/172] Analyze additional operators --- .../jetbrains/dukat/js/type/analysis/expression.kt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 9e75c0997..7a0c01f96 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -25,23 +25,30 @@ fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Con val leftConstraints = left.calculateConstraints(owner) return when (operator) { + // Assignments "=" -> { owner[left] = rightConstraints rightConstraints } + "-=", "*=", "/=", "%=", "**=", "&=", "^=", "|=", "<<=", ">>=", ">>>=" -> { + owner[left] = ConstraintContainer(NumberTypeConstraint) + ConstraintContainer(NumberTypeConstraint) + } + + // Non-assignments "&&", "||" -> { //TODO make this branching leftConstraints } - "-", "*", "/", "**", "%", "++", "--", "-=", "*=", "/=", "%=", "**=" -> { + "-", "*", "/", "**", "%", "++", "--" -> { rightConstraints += NumberTypeConstraint leftConstraints += NumberTypeConstraint ConstraintContainer(NumberTypeConstraint) } - "&", "|", "^", "<<", ">>" -> { + "&", "|", "^", "<<", ">>", ">>>" -> { ConstraintContainer(NumberTypeConstraint) } - "==", "===", "!=", "!==", ">", "<", ">=", "<=", "in" -> { + "==", "===", "!=", "!==", ">", "<", ">=", "<=", "in", "instanceof" -> { ConstraintContainer(BooleanTypeConstraint) } else -> { From 5d87de7fa28475b60783df8b78a17151e88cdf16 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2019 13:49:42 +0100 Subject: [PATCH 040/172] Seperate JS and TS translation. Add JS translation test. --- .idea/runConfigurations/JSTypeTests.xml | 22 +++ compiler/build.gradle | 30 ++++ compiler/test/data/javascript/function.d.kt | 61 ++++++++ compiler/test/data/javascript/function.d.ts | 142 ++++++++++++++++++ .../dukat/compiler/tests/BundleTranslator.kt | 13 +- .../dukat/compiler/tests/core/JSTypeTests.kt | 72 +++++++++ javascript/js-translator/build.gradle | 12 ++ .../dukat/js/translator/JavaScriptLowerer.kt | 15 ++ settings.gradle | 2 + .../dukat/ts/translator/ECMAScriptLowerer.kt | 11 ++ .../JsRuntimeByteArrayTranslator.kt | 16 +- .../ts/translator/JsRuntimeFileTranslator.kt | 13 +- ...nputTranslator.kt => TypescriptLowerer.kt} | 10 +- 13 files changed, 404 insertions(+), 15 deletions(-) create mode 100644 .idea/runConfigurations/JSTypeTests.xml create mode 100644 compiler/test/data/javascript/function.d.kt create mode 100644 compiler/test/data/javascript/function.d.ts create mode 100644 compiler/test/src/org/jetbrains/dukat/compiler/tests/core/JSTypeTests.kt create mode 100644 javascript/js-translator/build.gradle create mode 100644 javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt create mode 100644 typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/ECMAScriptLowerer.kt rename typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/{TypescriptInputTranslator.kt => TypescriptLowerer.kt} (94%) diff --git a/.idea/runConfigurations/JSTypeTests.xml b/.idea/runConfigurations/JSTypeTests.xml new file mode 100644 index 000000000..4c52fd210 --- /dev/null +++ b/.idea/runConfigurations/JSTypeTests.xml @@ -0,0 +1,22 @@ + + + + + + + + + \ No newline at end of file diff --git a/compiler/build.gradle b/compiler/build.gradle index 00f9db310..e5a6d78f4 100644 --- a/compiler/build.gradle +++ b/compiler/build.gradle @@ -51,6 +51,7 @@ dependencies { implementation(project(":idl-reference-resolver")) implementation(project(":itertools")) implementation(project(":js-type-analysis")) + implementation(project(":js-translator")) implementation(project(":logging")) implementation(project(":model-lowerings")) implementation(project(":model-lowerings-common")) @@ -168,6 +169,33 @@ task generateBinary(type: NodeTask) { ] + files } +task generateJSBinary(type: NodeTask) { + def scriptName = "${project(":ts-converter").buildDir}/bundle/runtime.js" + script = file(scriptName) + + def declarationsDir = "${project.projectDir}/test/data/javascript" + + inputs.dir(declarationsDir) + inputs.file(scriptName) + inputs.file(DEFAULT_LIB_PATH) + + def outputFile = "${project.buildDir}/javascript/declarations.dukat" + outputs.file(outputFile) + + def files = [] + file(declarationsDir) + .eachFileRecurse() { + if (it.isFile() && it.name.endsWith(".d.ts")) { + files << it + } + } + + args = [ + DEFAULT_LIB_PATH, + outputFile + ] + files +} + task extractKoltinJsLibs(type: Copy) { configurations.kotlinJsLibs.each { from it.absolutePath @@ -179,6 +207,7 @@ task extractKoltinJsLibs(type: Copy) { } generateBinary.dependsOn = [":ts-converter:webpack"] +generateJSBinary.dependsOn = [":ts-converter:webpack"] //TODO: having download and downloadDist is a shame @@ -186,6 +215,7 @@ test.dependsOn = [ download, downloadDist, generateBinary, + generateJSBinary, fetchDefinitelyTyped, extractKoltinJsLibs, ":node-package:nodeEnv", diff --git a/compiler/test/data/javascript/function.d.kt b/compiler/test/data/javascript/function.d.kt new file mode 100644 index 000000000..26f1ecdf6 --- /dev/null +++ b/compiler/test/data/javascript/function.d.kt @@ -0,0 +1,61 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external var num: Number + +external var bool: Boolean + +external var str: String + +external fun numBinaryFun(a: Number, b: Number): Number + +external fun numUnaryFun(a: Number): Number + +external fun numReferenceFun(): Number + +external fun boolBinaryFun(a: Any?, b: Any?): Boolean + +external fun boolUnaryFun(a: Any?): Boolean + +external fun boolReferenceFun(): Boolean + +external fun stringReferenceFun(): String + +external fun anyFun(a: Any?, b: Any?): Any? + +external fun unitFunction() + +external fun typeOf(o: Any?): String + +external fun instanceOfObject(o: Any?): Boolean + +external open class Literals { + companion object { + fun getStringLiteral(): String + fun getNumberLiteral(): Number + fun getBooleanLiteral(): Boolean + } +} + +external open class TestSet { + open fun isElement(obj: Any?): Boolean + open fun isObject(obj: Any?): Boolean + open fun isArray(obj: Any?): Boolean + open fun isArrayLike(collection: Any?): Boolean + open fun keyInObj(key: Any?, obj: Any?): Boolean + open fun negate(predicate: Any?): Boolean +} \ No newline at end of file diff --git a/compiler/test/data/javascript/function.d.ts b/compiler/test/data/javascript/function.d.ts new file mode 100644 index 000000000..523ac0467 --- /dev/null +++ b/compiler/test/data/javascript/function.d.ts @@ -0,0 +1,142 @@ +export var num = 3 +export var bool = true +export var str = "text" + +export function numBinaryFun(a, b) { + return a - b +} + +export function numUnaryFun(a) { + var b = a + a = "text" + return b++ +} + +export function numReferenceFun() { + return num +} + +export function boolBinaryFun(a, b) { + return a == b +} + +export function boolUnaryFun(a) { + return !a +} + +export function boolReferenceFun() { + return bool +} + +export function stringReferenceFun() { + return str +} + +export function anyFun(a, b) { + return a + b +} + +export function unitFunction() { + return; +} + +export function typeOf(o) { + return typeof o +} + +export function instanceOfObject(o) { + return o instanceof Object +} + +export class Literals { + static getStringLiteral() { + return "text" + } + + static getNumberLiteral() { + return 3.141592653 + } + + static getBooleanLiteral() { + return false + } +} + +export class TestSet { + isElement(obj) { + return !!(obj && obj.nodeType === 1); + } + + isObject(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + } + + isArray(obj) { + return toString.call(obj) === '[object Array]'; + } + + isArrayLike(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + } + + keyInObj(key, obj) { + return key in obj; + } + + //Originally returns a function (this was skipped for testing) + negate(predicate) { + return !predicate.apply(this, arguments); + } +} + +/* +// ??? +// Retrieve the values of an object's properties. +// Array +export _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; +}; +// Retrieve the names of an object's own properties. +// Delegates to **ECMAScript 5**'s native Object.keys. +_.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; +}; +// Generator function to create the findIndex and findLastIndex functions. +var createPredicateIndexFinder = function(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; +}; +_.negate = function(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; +}; +// Is a given array, string, or object empty? +// An "empty" object has no enumerable own-properties. +_.isEmpty = function(obj) { + if (obj == null) return true; isEmpty1 => boolean + if (isArrayLike(obj) && (.isArray(obj) || .isString(obj) || _.isArguments(obj))) return obj.length === 0; isEmpty2 => boolean + return _.keys(obj).length === 0; isEmpty3 => boolean +}; +*/ \ No newline at end of file diff --git a/compiler/test/src/org/jetbrains/dukat/compiler/tests/BundleTranslator.kt b/compiler/test/src/org/jetbrains/dukat/compiler/tests/BundleTranslator.kt index 3c64e0555..6e5dcbcd5 100644 --- a/compiler/test/src/org/jetbrains/dukat/compiler/tests/BundleTranslator.kt +++ b/compiler/test/src/org/jetbrains/dukat/compiler/tests/BundleTranslator.kt @@ -2,15 +2,18 @@ package org.jetbrains.dukat.compiler.tests import org.jetbrains.dukat.astModel.SourceSetModel import org.jetbrains.dukat.moduleNameResolver.ConstNameResolver +import org.jetbrains.dukat.ts.translator.ECMAScriptLowerer +import org.jetbrains.dukat.ts.translator.JsRuntimeByteArrayTranslator +import org.jetbrains.dukat.ts.translator.TypescriptLowerer import org.jetbrains.dukat.ts.translator.createJsByteArrayTranslator import org.jetbrains.dukat.tsmodel.SourceSetDeclaration import java.io.File -class BundleTranslator(private val inputName: String) { - - companion object { - val byteTranslator = createJsByteArrayTranslator(ConstNameResolver()) - } +class BundleTranslator( + private val inputName: String, + lowerer: ECMAScriptLowerer = TypescriptLowerer(ConstNameResolver()) +) { + private val byteTranslator = JsRuntimeByteArrayTranslator(lowerer) private val myMap = build() diff --git a/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/JSTypeTests.kt b/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/JSTypeTests.kt new file mode 100644 index 000000000..58b6c5de3 --- /dev/null +++ b/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/JSTypeTests.kt @@ -0,0 +1,72 @@ +package org.jetbrains.dukat.compiler.tests.core + +import org.jetbrains.dukat.compiler.tests.BundleTranslator +import org.jetbrains.dukat.compiler.tests.FileFetcher +import org.jetbrains.dukat.compiler.tests.OutputTests +import org.jetbrains.dukat.compiler.tests.core.TestConfig.CONVERTER_SOURCE_PATH +import org.jetbrains.dukat.compiler.tests.core.TestConfig.DEFAULT_LIB_PATH +import org.jetbrains.dukat.compiler.tests.core.TestConfig.NODE_PATH +import org.jetbrains.dukat.js.translator.JavaScriptLowerer +import org.jetbrains.dukat.moduleNameResolver.ConstNameResolver +import org.jetbrains.dukat.translator.InputTranslator +import org.jetbrains.dukat.translatorString.TS_DECLARATION_EXTENSION +import org.jetbrains.dukat.translatorString.translateModule +import org.jetbrains.dukat.ts.translator.JsRuntimeFileTranslator +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.MethodSource +import java.io.File +import kotlin.test.assertEquals + +class JSTypeTests : OutputTests() { + + @DisplayName("js type test set") + @ParameterizedTest(name = "{0}") + @MethodSource("jsSet") + fun withValueSource(name: String, jsPath: String, ktPath: String) { + assertContentEqualsBinary(name, jsPath, ktPath) + } + + //Never used + override fun getTranslator(): InputTranslator = JsRuntimeFileTranslator(JavaScriptLowerer(ConstNameResolver()), CONVERTER_SOURCE_PATH, DEFAULT_LIB_PATH, NODE_PATH) + + companion object : FileFetcher() { + + private val bundle = BundleTranslator("./build/javascript/declarations.dukat", JavaScriptLowerer(ConstNameResolver())) + + override val postfix = TS_DECLARATION_EXTENSION + + @JvmStatic + fun jsSet(): Array> { + return fileSetWithDescriptors("./test/data/javascript") + } + } + + + protected fun assertContentEqualsBinary( + descriptor: String, + tsPath: String, + ktPath: String + ) { + + val targetShortName = "${descriptor}.d.kt" + + val modules = translateModule(bundle.translate(tsPath)) + val translated = concatenate(tsPath, modules) + + assertEquals( + translated, + File(ktPath).readText().trimEnd(), + "\nSOURCE:\tfile:///${tsPath}\nTARGET:\tfile:///${ktPath}" + ) + + val outputDirectory = File("./build/tests/out") + translated.let { + val outputFile = outputDirectory.resolve(targetShortName) + outputFile.parentFile.mkdirs() + outputFile.writeText(translated) + } + } + +} + diff --git a/javascript/js-translator/build.gradle b/javascript/js-translator/build.gradle new file mode 100644 index 000000000..01aa57428 --- /dev/null +++ b/javascript/js-translator/build.gradle @@ -0,0 +1,12 @@ +plugins { + id 'kotlin' +} + +dependencies { + implementation(project(":ast-common")) + implementation(project(":ast-model")) + implementation(project(":js-type-analysis")) + implementation(project(":ts-model")) + implementation(project(":ts-translator")) + implementation(project(":module-name-resolver")) +} \ No newline at end of file diff --git a/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt b/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt new file mode 100644 index 000000000..77f27cde6 --- /dev/null +++ b/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt @@ -0,0 +1,15 @@ +package org.jetbrains.dukat.js.translator + +import org.jetbrains.dukat.astModel.SourceSetModel +import org.jetbrains.dukat.js.type.analysis.introduceTypes +import org.jetbrains.dukat.moduleNameResolver.ModuleNameResolver +import org.jetbrains.dukat.ts.translator.TypescriptLowerer +import org.jetbrains.dukat.tsmodel.SourceSetDeclaration + +class JavaScriptLowerer(nameResolver: ModuleNameResolver) : TypescriptLowerer(nameResolver) { + override fun lower(sourceSet: SourceSetDeclaration): SourceSetModel { + return super.lower(sourceSet + .introduceTypes() + ) + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index f4c86a671..1f64203f7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -54,6 +54,7 @@ include 'idl-reference-resolver' include 'interop' include 'itertools' include 'js-module-statistics' +include 'js-translator' include 'js-type-analysis' include 'logging' include 'model-lowerings' @@ -79,6 +80,7 @@ project(':idl-parser').projectDir = file("$rootDir/idl/idl-parser") project(':idl-reference-resolver').projectDir = file("$rootDir/idl/idl-reference-resolver") project(':js-module-statistics').projectDir = file("$rootDir/javascript/js-module-statistics") +project(':js-translator').projectDir = file("$rootDir/javascript/js-translator") project(':js-type-analysis').projectDir = file("$rootDir/javascript/js-type-analysis") project(':ts-ast-declarations').projectDir = file("$rootDir/typescript/ts-ast-declarations") diff --git a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/ECMAScriptLowerer.kt b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/ECMAScriptLowerer.kt new file mode 100644 index 000000000..c1bc7248e --- /dev/null +++ b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/ECMAScriptLowerer.kt @@ -0,0 +1,11 @@ +package org.jetbrains.dukat.ts.translator + +import org.jetbrains.dukat.astModel.SourceBundleModel +import org.jetbrains.dukat.astModel.SourceSetModel +import org.jetbrains.dukat.tsmodel.SourceBundleDeclaration +import org.jetbrains.dukat.tsmodel.SourceSetDeclaration + +interface ECMAScriptLowerer { + fun lower(sourceSet: SourceSetDeclaration): SourceSetModel + fun lower(sourceBundle: SourceBundleDeclaration): SourceBundleModel +} \ No newline at end of file diff --git a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeByteArrayTranslator.kt b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeByteArrayTranslator.kt index 23b98b9d7..e651ec88e 100644 --- a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeByteArrayTranslator.kt +++ b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeByteArrayTranslator.kt @@ -2,17 +2,29 @@ package org.jetbrains.dukat.ts.translator import dukat.ast.proto.Declarations import org.jetbrains.dukat.astModel.SourceBundleModel +import org.jetbrains.dukat.astModel.SourceSetModel import org.jetbrains.dukat.logger.Logging import org.jetbrains.dukat.moduleNameResolver.ModuleNameResolver +import org.jetbrains.dukat.translator.InputTranslator import org.jetbrains.dukat.tsmodel.SourceBundleDeclaration +import org.jetbrains.dukat.tsmodel.SourceSetDeclaration import org.jetbrains.dukat.tsmodel.factory.convert class JsRuntimeByteArrayTranslator( - override val moduleNameResolver: ModuleNameResolver -) : TypescriptInputTranslator { + private val lowerer: ECMAScriptLowerer +) : InputTranslator { + constructor(nameResolver: ModuleNameResolver) : this(TypescriptLowerer(nameResolver)) private val logger = Logging.logger(JsRuntimeByteArrayTranslator::class.simpleName.toString()) + fun lower(sourceSet: SourceSetDeclaration): SourceSetModel { + return lowerer.lower(sourceSet) + } + + private fun lower(sourceBundle: SourceBundleDeclaration): SourceBundleModel { + return lowerer.lower(sourceBundle) + } + fun parse(data: ByteArray): SourceBundleDeclaration { return Declarations.SourceSetBundleProto.parseFrom(data).convert() } diff --git a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeFileTranslator.kt b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeFileTranslator.kt index 838325558..ce30a0201 100644 --- a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeFileTranslator.kt +++ b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeFileTranslator.kt @@ -4,17 +4,24 @@ import dukat.ast.proto.Declarations import org.jetbrains.dukat.astModel.SourceBundleModel import org.jetbrains.dukat.logger.Logging import org.jetbrains.dukat.moduleNameResolver.ModuleNameResolver +import org.jetbrains.dukat.translator.InputTranslator import org.jetbrains.dukat.tsmodel.SourceBundleDeclaration import org.jetbrains.dukat.tsmodel.factory.convert import java.io.InputStream import java.util.concurrent.TimeUnit class JsRuntimeFileTranslator( - override val moduleNameResolver: ModuleNameResolver, + private val lowerer: ECMAScriptLowerer, private val translatorPath: String, private val libPath: String, private val nodePath: String -) : TypescriptInputTranslator { +) : InputTranslator { + constructor( + nameResolver: ModuleNameResolver, + translatorPath: String, + libPath: String, + nodePath: String + ) : this(TypescriptLowerer(nameResolver), translatorPath, libPath, nodePath) private val logger = Logging.logger(JsRuntimeByteArrayTranslator::class.simpleName.toString()) @@ -36,6 +43,6 @@ class JsRuntimeFileTranslator( } override fun translate(data: String): SourceBundleModel { - return lower(translateFile(data)) + return lowerer.lower(translateFile(data)) } } diff --git a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/TypescriptInputTranslator.kt b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/TypescriptLowerer.kt similarity index 94% rename from typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/TypescriptInputTranslator.kt rename to typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/TypescriptLowerer.kt index 00e2b89ee..015fca4ae 100644 --- a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/TypescriptInputTranslator.kt +++ b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/TypescriptLowerer.kt @@ -44,10 +44,10 @@ import org.jetrbains.dukat.nodeLowering.lowerings.typeAlias.resolveTypeAliases import substituteTsStdLibEntities -interface TypescriptInputTranslator : InputTranslator { - val moduleNameResolver: ModuleNameResolver - - fun lower(sourceSet: SourceSetDeclaration): SourceSetModel { +open class TypescriptLowerer( + private val moduleNameResolver: ModuleNameResolver +) : ECMAScriptLowerer { + override fun lower(sourceSet: SourceSetDeclaration): SourceSetModel { return sourceSet .filterOutNonDeclarations() .substituteTsStdLibEntities() @@ -87,7 +87,7 @@ interface TypescriptInputTranslator : InputTranslator { .generateStdLib() } - fun lower(sourceBundle: SourceBundleDeclaration): SourceBundleModel { + override fun lower(sourceBundle: SourceBundleDeclaration): SourceBundleModel { return SourceBundleModel(sourceBundle.sources.map { source -> lower(source) }) } } \ No newline at end of file From 8b1b9080eb51bda43d1c4efb74b019eff0eafe20 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2019 14:08:02 +0100 Subject: [PATCH 041/172] Remove export modifiers from JS test --- compiler/test/data/javascript/function.d.ts | 32 ++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/compiler/test/data/javascript/function.d.ts b/compiler/test/data/javascript/function.d.ts index 523ac0467..98e43745f 100644 --- a/compiler/test/data/javascript/function.d.ts +++ b/compiler/test/data/javascript/function.d.ts @@ -1,54 +1,54 @@ -export var num = 3 -export var bool = true -export var str = "text" +var num = 3 +var bool = true +var str = "text" -export function numBinaryFun(a, b) { +function numBinaryFun(a, b) { return a - b } -export function numUnaryFun(a) { +function numUnaryFun(a) { var b = a a = "text" return b++ } -export function numReferenceFun() { +function numReferenceFun() { return num } -export function boolBinaryFun(a, b) { +function boolBinaryFun(a, b) { return a == b } -export function boolUnaryFun(a) { +function boolUnaryFun(a) { return !a } -export function boolReferenceFun() { +function boolReferenceFun() { return bool } -export function stringReferenceFun() { +function stringReferenceFun() { return str } -export function anyFun(a, b) { +function anyFun(a, b) { return a + b } -export function unitFunction() { +function unitFunction() { return; } -export function typeOf(o) { +function typeOf(o) { return typeof o } -export function instanceOfObject(o) { +function instanceOfObject(o) { return o instanceof Object } -export class Literals { +class Literals { static getStringLiteral() { return "text" } @@ -62,7 +62,7 @@ export class Literals { } } -export class TestSet { +class TestSet { isElement(obj) { return !!(obj && obj.nodeType === 1); } From 777f4f546dbd1fd0f204f0c0c1e35bc228c11ecb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2019 15:03:36 +0100 Subject: [PATCH 042/172] Add call expression --- .../src/ast/AstExpressionConverter.ts | 14 ++++++++++++++ .../ts-converter/src/ast/AstExpressionFactory.ts | 10 ++++++++++ typescript/ts-model-proto/src/Declarations.proto | 16 +++++++++++----- .../expression/CallExpressionDeclaration.kt | 8 ++++++++ .../dukat/tsmodel/factory/convertProtobuf.kt | 9 +++++++++ 5 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/CallExpressionDeclaration.kt diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index 7b138ecd8..ce24b65e3 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -1,6 +1,7 @@ import * as ts from "typescript-services-api"; import {Expression, IdentifierEntity, NameEntity} from "./ast"; import {AstExpressionFactory} from "./AstExpressionFactory"; +import {LeftHandSideExpression, NodeArray, TypeNode} from "../../.tsdeclarations/tsserverlibrary"; export class AstExpressionConverter { static createBinaryExpression(left: Expression, operator: string, right: Expression): Expression { @@ -15,6 +16,10 @@ export class AstExpressionConverter { return AstExpressionFactory.createTypeOfExpressionDeclarationAsExpression(expression); } + static createCallExpression(expression: Expression, args: Array) { + return AstExpressionFactory.createCallExpressionDeclarationAsExpression(expression, args); + } + static createPropertyAccessExpression(expression: Expression, name: IdentifierEntity) { return AstExpressionFactory.createPropertyAccessExpressionDeclarationAsExpression(expression, name); } @@ -82,6 +87,13 @@ export class AstExpressionConverter { ) } + static convertCallExpression(expression: ts.CallExpression): Expression { + return this.createCallExpression( + this.convertExpression(expression.expression), + expression.arguments.map(arg => this.convertExpression(arg)) + ) + } + static convertPropertyAccessExpression(expression: ts.PropertyAccessExpression): Expression { return this.createPropertyAccessExpression( this.convertExpression(expression.expression), @@ -171,6 +183,8 @@ export class AstExpressionConverter { return this.convertPostfixUnaryExpression(expression) } else if (ts.isTypeOfExpression(expression)) { return this.convertTypeOfExpression(expression); + } else if (ts.isCallExpression(expression)) { + return this.convertCallExpression(expression); } else if (ts.isPropertyAccessExpression(expression)) { return this.convertPropertyAccessExpression(expression) } else if (ts.isElementAccessExpression(expression)) { diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index fc0d92a74..cacb4e76b 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -36,6 +36,16 @@ export class AstExpressionFactory { return expressionProto; } + static createCallExpressionDeclarationAsExpression(expression: Expression, args: Array): Expression { + let callExpression = new declarations.CallExpressionDeclarationProto(); + callExpression.setExpression(expression); + callExpression.setArgumentsList(args); + + let expressionProto = new declarations.ExpressionDeclarationProto(); + expressionProto.setCallexpression(callExpression); + return expressionProto; + } + static createPropertyAccessExpressionDeclarationAsExpression(expression: Expression, name: IdentifierEntity): Expression { let propertyAccessExpression = new declarations.PropertyAccessExpressionDeclarationProto(); propertyAccessExpression.setExpression(expression); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 4d5b6464a..32fef8b24 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -221,6 +221,11 @@ message TypeOfExpressionDeclarationProto { ExpressionDeclarationProto expression = 1; } +message CallExpressionDeclarationProto { + ExpressionDeclarationProto expression = 1; + repeated ExpressionDeclarationProto arguments = 2; +} + message PropertyAccessExpressionDeclarationProto { ExpressionDeclarationProto expression = 1; IdentifierEntityProto name = 2; @@ -240,11 +245,12 @@ message ExpressionDeclarationProto { BinaryExpressionDeclarationProto binaryExpression = 1; UnaryExpressionDeclarationProto unaryExpression = 2; TypeOfExpressionDeclarationProto typeOfExpression = 3; - NameExpressionDeclarationProto nameExpression = 4; - LiteralExpressionDeclarationProto literalExpression = 5; - PropertyAccessExpressionDeclarationProto propertyAccessExpression = 6; - ElementAccessExpressionDeclarationProto elementAccessExpression = 7; - UnknownExpressionDeclarationProto unknownExpression = 8; + CallExpressionDeclarationProto callExpression = 4; + NameExpressionDeclarationProto nameExpression = 5; + LiteralExpressionDeclarationProto literalExpression = 6; + PropertyAccessExpressionDeclarationProto propertyAccessExpression = 7; + ElementAccessExpressionDeclarationProto elementAccessExpression = 8; + UnknownExpressionDeclarationProto unknownExpression = 9; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/CallExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/CallExpressionDeclaration.kt new file mode 100644 index 000000000..e078e5877 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/CallExpressionDeclaration.kt @@ -0,0 +1,8 @@ +package org.jetbrains.dukat.tsmodel.expression + +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +data class CallExpressionDeclaration( + val expression: ExpressionDeclaration, + val arguments: List +) : ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 0786f6491..de968c823 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -36,6 +36,7 @@ import org.jetbrains.dukat.tsmodel.TypeAliasDeclaration import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.CallExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.ElementAccessExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.TypeOfExpressionDeclaration @@ -367,6 +368,13 @@ fun Declarations.TypeOfExpressionDeclarationProto.convert(): TypeOfExpressionDec ) } +fun Declarations.CallExpressionDeclarationProto.convert(): CallExpressionDeclaration { + return CallExpressionDeclaration( + expression = expression.convert(), + arguments = argumentsList.map { it.convert() } + ) +} + fun Declarations.NameExpressionDeclarationProto.convert() : NameExpressionDeclaration { return when { name.hasIdentifier() -> IdentifierExpressionDeclaration(identifier = name.identifier.convert()) @@ -417,6 +425,7 @@ fun Declarations.ExpressionDeclarationProto.convert() : ExpressionDeclaration { hasBinaryExpression() -> binaryExpression.convert() hasUnaryExpression() -> unaryExpression.convert() hasTypeOfExpression() -> typeOfExpression.convert() + hasCallExpression() -> callExpression.convert() hasNameExpression() -> nameExpression.convert() hasLiteralExpression() -> literalExpression.convert() hasPropertyAccessExpression() -> propertyAccessExpression.convert() From b54017c2d36ec287409aeca1191c80fd8c183573 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2019 16:45:18 +0100 Subject: [PATCH 043/172] Derive types from called functions --- compiler/test/data/javascript/function.d.kt | 2 ++ compiler/test/data/javascript/function.d.ts | 4 ++++ .../dukat/js/type/analysis/expression.kt | 22 +++++++++++++++++++ .../unresolved/call/CallArgumentConstraint.kt | 22 +++++++++++++++++++ .../unresolved/call/CallResultConstraint.kt | 16 ++++++++++++++ .../unresolved/call/getResolvedFunction.kt | 16 ++++++++++++++ 6 files changed, 82 insertions(+) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallArgumentConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallResultConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/getResolvedFunction.kt diff --git a/compiler/test/data/javascript/function.d.kt b/compiler/test/data/javascript/function.d.kt index 26f1ecdf6..5ff0a7ac8 100644 --- a/compiler/test/data/javascript/function.d.kt +++ b/compiler/test/data/javascript/function.d.kt @@ -23,6 +23,8 @@ external var str: String external fun numBinaryFun(a: Number, b: Number): Number +external fun numBinaryFunWrapper(a: Number, b: Number): Number + external fun numUnaryFun(a: Number): Number external fun numReferenceFun(): Number diff --git a/compiler/test/data/javascript/function.d.ts b/compiler/test/data/javascript/function.d.ts index 98e43745f..3e1d2c283 100644 --- a/compiler/test/data/javascript/function.d.ts +++ b/compiler/test/data/javascript/function.d.ts @@ -6,6 +6,10 @@ function numBinaryFun(a, b) { return a - b } +function numBinaryFunWrapper(a, b) { + return numBinaryFun(a, b) +} + function numUnaryFun(a) { var b = a a = "text" diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 7a0c01f96..3a6a97558 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -8,9 +8,12 @@ import org.jetbrains.dukat.js.type.constraint.resolved.BooleanTypeConstraint import org.jetbrains.dukat.js.type.constraint.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.resolved.NumberTypeConstraint import org.jetbrains.dukat.js.type.constraint.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type.constraint.unresolved.call.CallArgumentConstraint +import org.jetbrains.dukat.js.type.constraint.unresolved.call.CallResultConstraint import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.CallExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.TypeOfExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration @@ -82,6 +85,24 @@ fun TypeOfExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Con return ConstraintContainer(StringTypeConstraint) } +fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { + val callTargetConstraints = expression.calculateConstraints(owner) + val argumentConstraints = arguments.map { it.calculateConstraints(owner) } + + argumentConstraints.forEachIndexed { argumentNumber, arg -> + arg += CallArgumentConstraint( + callTargetConstraints, + argumentConstraints, + argumentNumber + ) + } + + return ConstraintContainer(CallResultConstraint( + callTargetConstraints, + argumentConstraints + )) +} + fun LiteralExpressionDeclaration.calculateConstraints() : ConstraintContainer { return when (this) { is StringLiteralExpressionDeclaration -> ConstraintContainer(StringTypeConstraint) @@ -98,6 +119,7 @@ fun ExpressionDeclaration?.calculateConstraints(owner: PropertyOwner) : Constrai is BinaryExpressionDeclaration -> this.calculateConstraints(owner) is UnaryExpressionDeclaration -> this.calculateConstraints(owner) is TypeOfExpressionDeclaration -> this.calculateConstraints(owner) + is CallExpressionDeclaration -> this.calculateConstraints(owner) is LiteralExpressionDeclaration -> this.calculateConstraints() null -> ConstraintContainer() else -> ConstraintContainer(NoTypeConstraint) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallArgumentConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallArgumentConstraint.kt new file mode 100644 index 000000000..ed02df67f --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallArgumentConstraint.kt @@ -0,0 +1,22 @@ +package org.jetbrains.dukat.js.type.constraint.unresolved.call + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.constraint.unresolved.FunctionConstraint + +data class CallArgumentConstraint( + val callTarget: ConstraintContainer, + val arguments: List, + val argumentNum: Int +) : Constraint { + override fun resolve(owner: PropertyOwner): Constraint { + val functionConstraint = callTarget.getResolvedFunctionConstraint(owner) + + return if (functionConstraint != null && functionConstraint.parameterConstraints.size >= argumentNum) { + return functionConstraint.parameterConstraints[argumentNum].second + } else { + ConstraintContainer() + } + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallResultConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallResultConstraint.kt new file mode 100644 index 000000000..93a2f7b9a --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallResultConstraint.kt @@ -0,0 +1,16 @@ +package org.jetbrains.dukat.js.type.constraint.unresolved.call + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner + +data class CallResultConstraint( + val callTarget: ConstraintContainer, + val arguments: List +) : Constraint { + override fun resolve(owner: PropertyOwner): Constraint { + val functionConstraint = callTarget.getResolvedFunctionConstraint(owner) + + return functionConstraint?.returnConstraints ?: ConstraintContainer() + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/getResolvedFunction.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/getResolvedFunction.kt new file mode 100644 index 000000000..dc5598902 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/getResolvedFunction.kt @@ -0,0 +1,16 @@ +package org.jetbrains.dukat.js.type.constraint.unresolved.call + +import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer +import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.constraint.unresolved.FunctionConstraint + +internal fun ConstraintContainer.getResolvedFunctionConstraint(owner: PropertyOwner) : FunctionConstraint? { + return when (val resolvedCallTarget = this.resolve(owner)) { + is ConstraintContainer -> { + val callTargetConstraints = resolvedCallTarget.getFlatConstraints() + return callTargetConstraints.firstOrNull { it is FunctionConstraint } as FunctionConstraint? + } + is FunctionConstraint -> resolvedCallTarget + else -> null + } +} \ No newline at end of file From c885f6eba93d6c0d66e38253746f7eda0192ab68 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2019 16:59:02 +0100 Subject: [PATCH 044/172] Fix regex literal expression protobuf conversion --- typescript/ts-converter/src/ast/AstExpressionFactory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index cacb4e76b..c9426f977 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -153,7 +153,7 @@ export class AstExpressionFactory { regExLiteralExpression.setValue(value); let literalExpression = new declarations.LiteralExpressionDeclarationProto(); - literalExpression.setRegExliteral(regExLiteralExpression); + literalExpression.setRegexliteral(regExLiteralExpression); return this.asExpression(literalExpression); } } \ No newline at end of file From 8c4e966726af668bc12952465adf3db64e68f809 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Nov 2019 14:25:58 +0100 Subject: [PATCH 045/172] Remove need of 'ConstraintContainer', instead having each constraint manage modifications to it itself --- .../dukat/js/type/analysis/expression.kt | 76 ++++++++-------- .../dukat/js/type/analysis/introduceTypes.kt | 56 ++++++------ .../dukat/js/type/constraint/Constraint.kt | 10 ++- .../composite/CompositeConstraint.kt | 45 ++++++++++ .../composite/ReferenceConstraint.kt | 14 +++ .../container/ConstraintContainer.kt | 35 -------- .../immutable/ImmutableConstraint.kt | 7 ++ .../call/CallArgumentConstraint.kt | 16 ++-- .../immutable/call/CallResultConstraint.kt | 18 ++++ .../immutable/call/getResolvedFunction.kt | 13 +++ .../resolved/BigIntTypeConstraint.kt | 3 + .../resolved/BooleanTypeConstraint.kt | 3 + .../immutable/resolved/NoTypeConstraint.kt | 3 + .../resolved/NumberTypeConstraint.kt | 3 + .../immutable/resolved/ResolvedConstraint.kt | 8 ++ .../resolved/StringTypeConstraint.kt | 3 + .../immutable/resolved/VoidTypeConstraint.kt | 3 + .../ClassConstraint.kt | 17 ++-- .../properties/FunctionConstraint.kt | 17 ++++ .../ObjectConstraint.kt | 15 ++-- .../properties/PropertyOwnerConstraint.kt | 8 ++ .../type/constraint/property_owner/Scope.kt | 22 ----- .../resolution/constraintToDeclaration.kt | 87 ++++++++----------- .../resolved/BigIntTypeConstraint.kt | 3 - .../resolved/BooleanTypeConstraint.kt | 3 - .../constraint/resolved/NoTypeConstraint.kt | 3 - .../resolved/NumberTypeConstraint.kt | 3 - .../constraint/resolved/ResolvedConstraint.kt | 8 -- .../resolved/StringTypeConstraint.kt | 3 - .../unresolved/FunctionConstraint.kt | 34 -------- .../unresolved/ReferenceConstraint.kt | 13 --- .../unresolved/call/CallResultConstraint.kt | 16 ---- .../unresolved/call/getResolvedFunction.kt | 16 ---- .../type/export_resolution/ExportResolver.kt | 2 +- .../GeneralExportResolver.kt | 2 +- .../property_owner/PropertyOwner.kt | 24 ++--- .../dukat/js/type/property_owner/Scope.kt | 22 +++++ .../org/jetbrains/dukat/js/type/type/types.kt | 2 +- 38 files changed, 318 insertions(+), 318 deletions(-) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/ReferenceConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/container/ConstraintContainer.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/ImmutableConstraint.kt rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/{unresolved => immutable}/call/CallArgumentConstraint.kt (52%) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallResultConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/getResolvedFunction.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/BigIntTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/BooleanTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/NoTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/NumberTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ResolvedConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/StringTypeConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/VoidTypeConstraint.kt rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/{unresolved => properties}/ClassConstraint.kt (58%) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/{unresolved => properties}/ObjectConstraint.kt (66%) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/Scope.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BigIntTypeConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BooleanTypeConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NoTypeConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NumberTypeConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/ResolvedConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/StringTypeConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/FunctionConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ReferenceConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallResultConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/getResolvedFunction.kt rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/{constraint => }/property_owner/PropertyOwner.kt (80%) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 3a6a97558..23ad95b91 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -1,15 +1,17 @@ package org.jetbrains.dukat.js.type.analysis -import org.jetbrains.dukat.js.type.constraint.unresolved.ReferenceConstraint -import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner -import org.jetbrains.dukat.js.type.constraint.resolved.BigIntTypeConstraint -import org.jetbrains.dukat.js.type.constraint.resolved.BooleanTypeConstraint -import org.jetbrains.dukat.js.type.constraint.resolved.NoTypeConstraint -import org.jetbrains.dukat.js.type.constraint.resolved.NumberTypeConstraint -import org.jetbrains.dukat.js.type.constraint.resolved.StringTypeConstraint -import org.jetbrains.dukat.js.type.constraint.unresolved.call.CallArgumentConstraint -import org.jetbrains.dukat.js.type.constraint.unresolved.call.CallResultConstraint +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.composite.ReferenceConstraint +import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.call.CallArgumentConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.call.CallResultConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration @@ -23,7 +25,7 @@ import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDe import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration -fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { +fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { val rightConstraints = right.calculateConstraints(owner) val leftConstraints = left.calculateConstraints(owner) @@ -34,8 +36,8 @@ fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Con rightConstraints } "-=", "*=", "/=", "%=", "**=", "&=", "^=", "|=", "<<=", ">>=", ">>>=" -> { - owner[left] = ConstraintContainer(NumberTypeConstraint) - ConstraintContainer(NumberTypeConstraint) + owner[left] = NumberTypeConstraint + NumberTypeConstraint } // Non-assignments @@ -46,46 +48,46 @@ fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Con "-", "*", "/", "**", "%", "++", "--" -> { rightConstraints += NumberTypeConstraint leftConstraints += NumberTypeConstraint - ConstraintContainer(NumberTypeConstraint) + NumberTypeConstraint } "&", "|", "^", "<<", ">>", ">>>" -> { - ConstraintContainer(NumberTypeConstraint) + NumberTypeConstraint } "==", "===", "!=", "!==", ">", "<", ">=", "<=", "in", "instanceof" -> { - ConstraintContainer(BooleanTypeConstraint) + BooleanTypeConstraint } else -> { - ConstraintContainer(NoTypeConstraint) + CompositeConstraint(NoTypeConstraint) } } } -fun UnaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { +fun UnaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { val operandConstraints = operand.calculateConstraints(owner) return when (operator) { "--", "++", "~" -> { operandConstraints += NumberTypeConstraint - ConstraintContainer(NumberTypeConstraint) + NumberTypeConstraint } "-", "+" -> { - ConstraintContainer(NumberTypeConstraint) + NumberTypeConstraint } "!" -> { - ConstraintContainer(BooleanTypeConstraint) + BooleanTypeConstraint } else -> { - ConstraintContainer(NoTypeConstraint) + CompositeConstraint(NoTypeConstraint) } } } -fun TypeOfExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { +fun TypeOfExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { expression.calculateConstraints(owner) - return ConstraintContainer(StringTypeConstraint) + return StringTypeConstraint } -fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { +fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { val callTargetConstraints = expression.calculateConstraints(owner) val argumentConstraints = arguments.map { it.calculateConstraints(owner) } @@ -97,31 +99,31 @@ fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Const ) } - return ConstraintContainer(CallResultConstraint( + return CallResultConstraint( callTargetConstraints, argumentConstraints - )) + ) } -fun LiteralExpressionDeclaration.calculateConstraints() : ConstraintContainer { +fun LiteralExpressionDeclaration.calculateConstraints() : Constraint { return when (this) { - is StringLiteralExpressionDeclaration -> ConstraintContainer(StringTypeConstraint) - is NumericLiteralExpressionDeclaration -> ConstraintContainer(NumberTypeConstraint) - is BigIntLiteralExpressionDeclaration -> ConstraintContainer(BigIntTypeConstraint) - is BooleanLiteralExpressionDeclaration -> ConstraintContainer(BooleanTypeConstraint) - else -> raiseConcern("Unexpected literal expression type <${this::class}>") { ConstraintContainer(NoTypeConstraint) } + is StringLiteralExpressionDeclaration -> StringTypeConstraint + is NumericLiteralExpressionDeclaration -> NumberTypeConstraint + is BigIntLiteralExpressionDeclaration -> BigIntTypeConstraint + is BooleanLiteralExpressionDeclaration -> BooleanTypeConstraint + else -> raiseConcern("Unexpected literal expression type <${this::class}>") { CompositeConstraint(NoTypeConstraint) } } } -fun ExpressionDeclaration?.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { +fun ExpressionDeclaration?.calculateConstraints(owner: PropertyOwner) : Constraint { return when (this) { - is IdentifierExpressionDeclaration -> owner[this] ?: ConstraintContainer(ReferenceConstraint(this.identifier)) + is IdentifierExpressionDeclaration -> owner[this] ?: ReferenceConstraint(this.identifier) is BinaryExpressionDeclaration -> this.calculateConstraints(owner) is UnaryExpressionDeclaration -> this.calculateConstraints(owner) is TypeOfExpressionDeclaration -> this.calculateConstraints(owner) is CallExpressionDeclaration -> this.calculateConstraints(owner) is LiteralExpressionDeclaration -> this.calculateConstraints() - null -> ConstraintContainer() - else -> ConstraintContainer(NoTypeConstraint) + null -> VoidTypeConstraint + else -> CompositeConstraint() } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index 705743143..97ebe7932 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -1,11 +1,13 @@ package org.jetbrains.dukat.js.type.analysis import org.jetbrains.dukat.astCommon.IdentifierEntity -import org.jetbrains.dukat.js.type.constraint.unresolved.ClassConstraint -import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer -import org.jetbrains.dukat.js.type.constraint.unresolved.FunctionConstraint -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner -import org.jetbrains.dukat.js.type.constraint.property_owner.Scope +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint +import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint +import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.property_owner.Scope import org.jetbrains.dukat.js.type.export_resolution.GeneralExportResolver import org.jetbrains.dukat.js.type.export_resolution.ExportResolver import org.jetbrains.dukat.panic.raiseConcern @@ -27,36 +29,30 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) { if (this.body != null) { val functionScope = Scope() - val parameterConstraintContainers = MutableList(parameters.size) { i -> + val parameterConstraints = MutableList(parameters.size) { i -> // Store constraints of parameters in scope, // and in parameter list (in case the variable is replaced) - val parameterConstraintContainer = ConstraintContainer() - functionScope[parameters[i].name] = parameterConstraintContainer - parameters[i].name to parameterConstraintContainer + val parameterConstraint = CompositeConstraint() + functionScope[parameters[i].name] = parameterConstraint + parameters[i].name to parameterConstraint } val returnTypeConstraints = body!!.calculateConstraints(functionScope) - owner[name] = ConstraintContainer(FunctionConstraint( + owner[name] = FunctionConstraint( returnConstraints = returnTypeConstraints, - parameterConstraints = parameterConstraintContainers - )) + parameterConstraints = parameterConstraints + ) } } -/*fun ConstructorDeclaration.addTo(owner: PropertyOwner) { +/* +fun ConstructorDeclaration.addTo(owner: PropertyOwner) { // TODO add body to constructor in AST and process it like a function } -fun InterfaceDeclaration.addTo(owner: PropertyOwner) { - val scope = Scope() - - for(member in members) { - member.calculateConstraints(scope) - } - - //owner[name] = scope -}*/ +fun InterfaceDeclaration.addTo(owner: PropertyOwner) +*/ fun MemberDeclaration.addTo(owner: PropertyOwner) { when (this) { @@ -79,13 +75,13 @@ fun ClassDeclaration.addTo(owner: PropertyOwner) { members.forEach { it.addToClass(classConstraint) } - owner[className.value] = ConstraintContainer(classConstraint) + owner[className.value] = classConstraint } else { raiseConcern("Cannot convert class with name of type <${className::class}>.") { } } } -fun BlockDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { +fun BlockDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { return statements.calculateConstraints(owner) } @@ -97,12 +93,12 @@ fun ExpressionStatementDeclaration.calculateConstraints(owner: PropertyOwner) { expression.calculateConstraints(owner) } -fun ReturnStatementDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { - return ConstraintContainer(expression.calculateConstraints(owner)) +fun ReturnStatementDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { + return expression.calculateConstraints(owner) } -fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintContainer? { - var returnTypeConstraints: ConstraintContainer? = null +fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint? { + var returnTypeConstraints: Constraint? = null when (this) { is FunctionDeclaration -> this.addTo(owner) @@ -119,8 +115,8 @@ fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner) : ConstraintC return returnTypeConstraints } -fun List.calculateConstraints(owner: PropertyOwner) : ConstraintContainer { - var returnTypeConstraints = ConstraintContainer() +fun List.calculateConstraints(owner: PropertyOwner) : Constraint { + var returnTypeConstraints: Constraint = VoidTypeConstraint for(statement in this) { val statementReturnTypeConstraints = statement.calculateConstraints(owner) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt index aace656be..29b3b7d22 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt @@ -1,7 +1,15 @@ package org.jetbrains.dukat.js.type.constraint -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner interface Constraint { + operator fun plusAssign(other: Constraint) + + operator fun plusAssign(others: Collection) { + others.forEach { + this += it + } + } + fun resolve(owner: PropertyOwner) : Constraint } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt new file mode 100644 index 000000000..a9d50afa1 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt @@ -0,0 +1,45 @@ +package org.jetbrains.dukat.js.type.constraint.composite + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import javax.lang.model.type.NoType + +class CompositeConstraint(private val constraints: MutableSet) : Constraint { + constructor(vararg constraints: Constraint) : this(mutableSetOf(*constraints)) + constructor(constraints: List) : this(constraints.toMutableSet()) + + override operator fun plusAssign(other: Constraint) { + constraints += other + } + + override operator fun plusAssign(others: Collection) { + constraints.addAll(others) + } + + fun getFlatConstraints() : List { + return constraints.flatMap { constraint -> + if(constraint is CompositeConstraint) { + constraint.getFlatConstraints() + } else { + listOf(constraint) + } + } + } + + override fun resolve(owner: PropertyOwner): Constraint { + val resolvedConstraints = getFlatConstraints().map { it.resolve(owner) } + + return when { + resolvedConstraints.contains(NumberTypeConstraint) -> NumberTypeConstraint + resolvedConstraints.contains(BigIntTypeConstraint) -> BigIntTypeConstraint + resolvedConstraints.contains(BooleanTypeConstraint) -> BooleanTypeConstraint + resolvedConstraints.contains(StringTypeConstraint) -> StringTypeConstraint + else -> NoTypeConstraint + } + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/ReferenceConstraint.kt new file mode 100644 index 000000000..ec892f4d3 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/ReferenceConstraint.kt @@ -0,0 +1,14 @@ +package org.jetbrains.dukat.js.type.constraint.composite + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner + +data class ReferenceConstraint( + val identifier: IdentifierEntity +) : ImmutableConstraint { //TODO make modifiable + override fun resolve(owner: PropertyOwner): Constraint { + return owner[identifier]?.resolve(owner) ?: this + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/container/ConstraintContainer.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/container/ConstraintContainer.kt deleted file mode 100644 index 4cb6b8a5e..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/container/ConstraintContainer.kt +++ /dev/null @@ -1,35 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.container - -import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner - -class ConstraintContainer(protected val constraints: MutableSet) : Constraint { - constructor(vararg constraints: Constraint) : this(mutableSetOf(*constraints)) - constructor(constraints: List) : this(constraints.toMutableSet()) - - operator fun plusAssign(constraint: Constraint) { - constraints += constraint - } - - operator fun plusAssign(newConstraints: Collection) { - constraints.addAll(newConstraints) - } - - fun copy() : ConstraintContainer { - return ConstraintContainer(constraints) - } - - fun getFlatConstraints() : List { - return constraints.flatMap { constraint -> - if(constraint is ConstraintContainer) { - constraint.getFlatConstraints() - } else { - listOf(constraint) - } - } - } - - override fun resolve(owner: PropertyOwner): Constraint { - return ConstraintContainer(getFlatConstraints().map { it.resolve(owner) }) - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/ImmutableConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/ImmutableConstraint.kt new file mode 100644 index 000000000..7be85bfcf --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/ImmutableConstraint.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.js.type.constraint.immutable + +import org.jetbrains.dukat.js.type.constraint.Constraint + +interface ImmutableConstraint : Constraint { + override operator fun plusAssign(other: Constraint) { /* do nothing */ } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallArgumentConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallArgumentConstraint.kt similarity index 52% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallArgumentConstraint.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallArgumentConstraint.kt index ed02df67f..fb37bbb3e 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallArgumentConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallArgumentConstraint.kt @@ -1,22 +1,22 @@ -package org.jetbrains.dukat.js.type.constraint.unresolved.call +package org.jetbrains.dukat.js.type.constraint.immutable.call import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner -import org.jetbrains.dukat.js.type.constraint.unresolved.FunctionConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint +import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner data class CallArgumentConstraint( - val callTarget: ConstraintContainer, - val arguments: List, + val callTarget: Constraint, + val arguments: List, val argumentNum: Int -) : Constraint { +) : ImmutableConstraint { override fun resolve(owner: PropertyOwner): Constraint { val functionConstraint = callTarget.getResolvedFunctionConstraint(owner) return if (functionConstraint != null && functionConstraint.parameterConstraints.size >= argumentNum) { return functionConstraint.parameterConstraints[argumentNum].second } else { - ConstraintContainer() + CompositeConstraint() } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallResultConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallResultConstraint.kt new file mode 100644 index 000000000..b19a3a1ea --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallResultConstraint.kt @@ -0,0 +1,18 @@ +package org.jetbrains.dukat.js.type.constraint.immutable.call + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner + +data class CallResultConstraint( + val callTarget: Constraint, + val arguments: List +) : ImmutableConstraint { + override fun resolve(owner: PropertyOwner): Constraint { + val functionConstraint = callTarget.getResolvedFunctionConstraint(owner) + + return functionConstraint?.returnConstraints ?: VoidTypeConstraint + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/getResolvedFunction.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/getResolvedFunction.kt new file mode 100644 index 000000000..6a071e422 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/getResolvedFunction.kt @@ -0,0 +1,13 @@ +package org.jetbrains.dukat.js.type.constraint.immutable.call + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint + +internal fun Constraint.getResolvedFunctionConstraint(owner: PropertyOwner) : FunctionConstraint? { + return when (val resolvedCallTarget = this.resolve(owner)) { + is FunctionConstraint -> resolvedCallTarget + else -> null + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/BigIntTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/BigIntTypeConstraint.kt new file mode 100644 index 000000000..296668dbc --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/BigIntTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.immutable.resolved + +object BigIntTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/BooleanTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/BooleanTypeConstraint.kt new file mode 100644 index 000000000..5f761b8d9 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/BooleanTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.immutable.resolved + +object BooleanTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/NoTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/NoTypeConstraint.kt new file mode 100644 index 000000000..397ce0224 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/NoTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.immutable.resolved + +object NoTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/NumberTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/NumberTypeConstraint.kt new file mode 100644 index 000000000..51b2c8a1d --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/NumberTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.immutable.resolved + +object NumberTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ResolvedConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ResolvedConstraint.kt new file mode 100644 index 000000000..feaf34241 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ResolvedConstraint.kt @@ -0,0 +1,8 @@ +package org.jetbrains.dukat.js.type.constraint.immutable.resolved + +import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner + +interface ResolvedConstraint : ImmutableConstraint { + override fun resolve(owner: PropertyOwner) = this +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/StringTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/StringTypeConstraint.kt new file mode 100644 index 000000000..a7f7bf70b --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/StringTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.immutable.resolved + +object StringTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/VoidTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/VoidTypeConstraint.kt new file mode 100644 index 000000000..b24fd9af7 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/VoidTypeConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.immutable.resolved + +object VoidTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ClassConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt similarity index 58% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ClassConstraint.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt index 0ef23cf84..0440e8f56 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ClassConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt @@ -1,16 +1,17 @@ -package org.jetbrains.dukat.js.type.constraint.unresolved +package org.jetbrains.dukat.js.type.constraint.properties +import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -class ClassConstraint(val prototype: ObjectConstraint = ObjectConstraint()) : PropertyOwner, Constraint { +class ClassConstraint(val prototype: ObjectConstraint = ObjectConstraint()) : PropertyOwnerConstraint { override val propertyNames: Set get() = staticMembers.keys - private val staticMembers = LinkedHashMap() + private val staticMembers = LinkedHashMap() - override fun set(name: String, data: ConstraintContainer) { + override fun set(name: String, data: Constraint) { staticMembers[name] = data } @@ -18,7 +19,7 @@ class ClassConstraint(val prototype: ObjectConstraint = ObjectConstraint()) : Pr return staticMembers.containsKey(name) } - override fun get(name: String): ConstraintContainer? { + override fun get(name: String): Constraint? { return staticMembers[name] } @@ -26,7 +27,7 @@ class ClassConstraint(val prototype: ObjectConstraint = ObjectConstraint()) : Pr val resolvedConstraint = ClassConstraint(prototype.resolve(owner) as ObjectConstraint) propertyNames.forEach { - resolvedConstraint[it] = ConstraintContainer(this[it]!!.resolve(owner)) + resolvedConstraint[it] = this[it]!!.resolve(owner) } return resolvedConstraint diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt new file mode 100644 index 000000000..8e4fe8c03 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt @@ -0,0 +1,17 @@ +package org.jetbrains.dukat.js.type.constraint.properties + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner + +class FunctionConstraint( + val returnConstraints: Constraint, + val parameterConstraints: List> +) : ImmutableConstraint { //TODO make property owner (since functions technically are, in javascript) + override fun resolve(owner: PropertyOwner): Constraint { + return FunctionConstraint( + returnConstraints.resolve(owner), + parameterConstraints.map { (name, constraint) -> name to constraint.resolve(owner) } + ) + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ObjectConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt similarity index 66% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ObjectConstraint.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt index d3344ea0c..2000d6e3e 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ObjectConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt @@ -1,12 +1,11 @@ -package org.jetbrains.dukat.js.type.constraint.unresolved +package org.jetbrains.dukat.js.type.constraint.properties import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class ObjectConstraint( private val instantiatedClass: ClassConstraint? = null -) : PropertyOwner, Constraint { +) : PropertyOwnerConstraint { override val propertyNames: Set get() { val names = mutableSetOf() @@ -17,9 +16,9 @@ class ObjectConstraint( return names } - private val properties = LinkedHashMap() + private val properties = LinkedHashMap() - override fun set(name: String, data: ConstraintContainer) { + override fun set(name: String, data: Constraint) { properties[name] = data } @@ -27,7 +26,7 @@ class ObjectConstraint( return properties.containsKey(name) || instantiatedClass?.prototype?.has(name) == true } - override fun get(name: String): ConstraintContainer? { + override fun get(name: String): Constraint? { return when { properties.containsKey(name) -> properties[name] instantiatedClass?.prototype?.has(name) == true -> instantiatedClass.prototype[name] @@ -39,7 +38,7 @@ class ObjectConstraint( val resolvedConstraint = ObjectConstraint() propertyNames.forEach { - resolvedConstraint[it] = ConstraintContainer(this[it]!!.resolve(owner)) + resolvedConstraint[it] = this[it]!!.resolve(owner) } return resolvedConstraint diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt new file mode 100644 index 000000000..c7765b017 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt @@ -0,0 +1,8 @@ +package org.jetbrains.dukat.js.type.constraint.properties + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner + +interface PropertyOwnerConstraint : PropertyOwner, Constraint { + override fun plusAssign(other: Constraint) {} +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/Scope.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/Scope.kt deleted file mode 100644 index f010fa5aa..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/Scope.kt +++ /dev/null @@ -1,22 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.property_owner - -import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer - -class Scope : PropertyOwner { - override val propertyNames: Set - get() = properties.keys - - private val properties = LinkedHashMap() - - override fun set(name: String, data: ConstraintContainer) { - properties[name] = data - } - - override fun has(name: String): Boolean { - return properties.containsKey(name) - } - - override fun get(name: String): ConstraintContainer? { - return properties[name] - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index 7c23a8f4c..3321f479e 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -2,18 +2,19 @@ package org.jetbrains.dukat.js.type.constraint.resolution import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer -import org.jetbrains.dukat.js.type.constraint.resolved.BigIntTypeConstraint -import org.jetbrains.dukat.js.type.constraint.resolved.BooleanTypeConstraint -import org.jetbrains.dukat.js.type.constraint.resolved.NumberTypeConstraint -import org.jetbrains.dukat.js.type.constraint.resolved.StringTypeConstraint -import org.jetbrains.dukat.js.type.constraint.unresolved.ClassConstraint -import org.jetbrains.dukat.js.type.constraint.unresolved.FunctionConstraint +import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint +import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint +import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.type.anyNullableType import org.jetbrains.dukat.js.type.type.booleanType import org.jetbrains.dukat.js.type.type.numberType import org.jetbrains.dukat.js.type.type.stringType -import org.jetbrains.dukat.js.type.type.unitType +import org.jetbrains.dukat.js.type.type.voidType import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration @@ -36,9 +37,9 @@ fun getVariableDeclaration(name: String, type: ParameterValueDeclaration) = Vari uid = getUID() ) -fun ConstraintContainer.toParameterDeclaration(name: String) = ParameterDeclaration( +fun Constraint.toParameterDeclaration(name: String) = ParameterDeclaration( name = name, - type = this.toType(), + type = this.toType() ?: anyNullableType, initializer = null, vararg = false, optional = false @@ -47,17 +48,25 @@ fun ConstraintContainer.toParameterDeclaration(name: String) = ParameterDeclarat fun FunctionConstraint.toDeclaration(name: String) = FunctionDeclaration( name = name, parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, - type = returnConstraints.toType(unitType), + type = returnConstraints.toType() ?: voidType, typeParameters = emptyList(), modifiers = EXPORT_MODIFIERS, body = null, uid = getUID() ) -fun ConstraintContainer.toMemberDeclaration(name: String, isStatic: Boolean) : MemberDeclaration? { - return when (val declaration = toDeclaration(name)) { - is FunctionDeclaration -> return declaration.copy(modifiers = if (isStatic) STATIC_MODIFIERS else emptyList()) - else -> raiseConcern("Cannot convert declaration of type <${declaration?.let {declaration::class} ?: "null"} to member.>") { null } +fun FunctionDeclaration.withStaticModifier(isStatic: Boolean) : FunctionDeclaration { + return this.copy(modifiers = if (isStatic) STATIC_MODIFIERS else emptyList()) +} + +fun FunctionConstraint.toMemberDeclaration(name: String, isStatic: Boolean) : MemberDeclaration? { + return this.toDeclaration(name).withStaticModifier(isStatic) +} + +fun Constraint.toMemberDeclaration(name: String, isStatic: Boolean) : MemberDeclaration? { + return when (this) { + is FunctionConstraint -> this.toMemberDeclaration(name, isStatic) + else -> raiseConcern("Cannot treat constraint of type <${this::class}> as member.") { null } } } @@ -86,48 +95,22 @@ fun ClassConstraint.toDeclaration(name: String) : ClassDeclaration { ) } -fun List.toType() : TypeDeclaration? { - return when { - this.contains(NumberTypeConstraint) -> numberType - this.contains(BigIntTypeConstraint) -> numberType - this.contains(BooleanTypeConstraint) -> booleanType - this.contains(StringTypeConstraint) -> stringType - this.isEmpty() -> null +fun Constraint.toType() : TypeDeclaration? { + return when (this) { + is NumberTypeConstraint -> numberType + is BigIntTypeConstraint -> numberType + is BooleanTypeConstraint -> booleanType + is StringTypeConstraint -> stringType + is VoidTypeConstraint -> voidType else -> anyNullableType } } -fun ConstraintContainer.toType(defaultType: TypeDeclaration = anyNullableType) : TypeDeclaration { - val flatConstraints = getFlatConstraints() - return flatConstraints.toType() ?: defaultType -} - -fun ConstraintContainer.toDeclaration(name: String) : TopLevelDeclaration? { - var declaration: TopLevelDeclaration? = null - - val flatConstraints = getFlatConstraints() - - flatConstraints.forEach { - when (it) { - is ClassConstraint -> declaration = it.toDeclaration(name) - is FunctionConstraint -> declaration = it.toDeclaration(name) - } - } - - if(declaration == null) { - val type = flatConstraints.toType() - - if(type != null) { - declaration = getVariableDeclaration(name, type) - } - } - - return declaration -} - fun Constraint.toDeclaration(name: String) : TopLevelDeclaration? { return when (this) { - is ConstraintContainer -> this.toDeclaration(name) - else -> raiseConcern("Export cannot be defined by constraint directly.") { null } + is ClassConstraint -> this.toDeclaration(name) + is FunctionConstraint -> this.toDeclaration(name) + is CompositeConstraint -> raiseConcern("Unexpected composited type for variable named '$name'. Should be resolved by this point!") { null } + else -> this.toType()?.let { type -> getVariableDeclaration(name, type) } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BigIntTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BigIntTypeConstraint.kt deleted file mode 100644 index 8680153b4..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BigIntTypeConstraint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.resolved - -object BigIntTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BooleanTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BooleanTypeConstraint.kt deleted file mode 100644 index ff0759d83..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/BooleanTypeConstraint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.resolved - -object BooleanTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NoTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NoTypeConstraint.kt deleted file mode 100644 index cd5dd4622..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NoTypeConstraint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.resolved - -object NoTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NumberTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NumberTypeConstraint.kt deleted file mode 100644 index 8296617b8..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/NumberTypeConstraint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.resolved - -object NumberTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/ResolvedConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/ResolvedConstraint.kt deleted file mode 100644 index 6a183cdf2..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/ResolvedConstraint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.resolved - -import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner - -interface ResolvedConstraint : Constraint { - override fun resolve(owner: PropertyOwner) = this -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/StringTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/StringTypeConstraint.kt deleted file mode 100644 index c118a240d..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolved/StringTypeConstraint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.resolved - -object StringTypeConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/FunctionConstraint.kt deleted file mode 100644 index 50cde0cc9..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/FunctionConstraint.kt +++ /dev/null @@ -1,34 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.unresolved - -import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner - -class FunctionConstraint( - val returnConstraints: ConstraintContainer, - val parameterConstraints: List> -) : PropertyOwner, Constraint { - override val propertyNames: Set - get() = properties.keys - - private val properties = LinkedHashMap() - - override fun set(name: String, data: ConstraintContainer) { - properties[name] = data - } - - override fun has(name: String): Boolean { - return properties.containsKey(name) - } - - override fun get(name: String): ConstraintContainer? { - return properties[name] - } - - override fun resolve(owner: PropertyOwner): Constraint { - return FunctionConstraint( - ConstraintContainer(returnConstraints.resolve(owner)), - parameterConstraints.map { (name, constraint) -> name to ConstraintContainer(constraint.resolve(owner)) } - ) - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ReferenceConstraint.kt deleted file mode 100644 index 7b77d5434..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/ReferenceConstraint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.unresolved - -import org.jetbrains.dukat.astCommon.IdentifierEntity -import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner - -data class ReferenceConstraint( - val identifier: IdentifierEntity -) : Constraint { - override fun resolve(owner: PropertyOwner): Constraint { - return owner[identifier] ?: this - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallResultConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallResultConstraint.kt deleted file mode 100644 index 93a2f7b9a..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/CallResultConstraint.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.unresolved.call - -import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner - -data class CallResultConstraint( - val callTarget: ConstraintContainer, - val arguments: List -) : Constraint { - override fun resolve(owner: PropertyOwner): Constraint { - val functionConstraint = callTarget.getResolvedFunctionConstraint(owner) - - return functionConstraint?.returnConstraints ?: ConstraintContainer() - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/getResolvedFunction.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/getResolvedFunction.kt deleted file mode 100644 index dc5598902..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/unresolved/call/getResolvedFunction.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.unresolved.call - -import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner -import org.jetbrains.dukat.js.type.constraint.unresolved.FunctionConstraint - -internal fun ConstraintContainer.getResolvedFunctionConstraint(owner: PropertyOwner) : FunctionConstraint? { - return when (val resolvedCallTarget = this.resolve(owner)) { - is ConstraintContainer -> { - val callTargetConstraints = resolvedCallTarget.getFlatConstraints() - return callTargetConstraints.firstOrNull { it is FunctionConstraint } as FunctionConstraint? - } - is FunctionConstraint -> resolvedCallTarget - else -> null - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt index 87ce776b2..14c2c1995 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt @@ -1,6 +1,6 @@ package org.jetbrains.dukat.js.type.export_resolution -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.tsmodel.TopLevelDeclaration interface ExportResolver { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt index 17f1177f5..8d5c6d31b 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt @@ -1,6 +1,6 @@ package org.jetbrains.dukat.js.type.export_resolution -import org.jetbrains.dukat.js.type.constraint.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.js.type.constraint.resolution.toDeclaration import org.jetbrains.dukat.tsmodel.TopLevelDeclaration diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/PropertyOwner.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt similarity index 80% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/PropertyOwner.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt index 2c96ac496..c3da3b7bb 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/property_owner/PropertyOwner.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt @@ -1,7 +1,7 @@ -package org.jetbrains.dukat.js.type.constraint.property_owner +package org.jetbrains.dukat.js.type.property_owner import org.jetbrains.dukat.astCommon.IdentifierEntity -import org.jetbrains.dukat.js.type.constraint.container.ConstraintContainer +import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration @@ -9,19 +9,19 @@ import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclarati interface PropertyOwner { val propertyNames: Set - operator fun set(name: String, data: ConstraintContainer) + operator fun set(name: String, data: Constraint) - operator fun set(identifier: IdentifierEntity, data: ConstraintContainer) { + operator fun set(identifier: IdentifierEntity, data: Constraint) { this[identifier.value] = data } - operator fun set(identifierExpression: IdentifierExpressionDeclaration, data: ConstraintContainer) { + operator fun set(identifierExpression: IdentifierExpressionDeclaration, data: Constraint) { this[identifierExpression.identifier] = data } - //operator fun set(propertyAccessExpression: PropertyAccessExpressionDeclaration, data: ConstraintContainer) + //operator fun set(propertyAccessExpression: PropertyAccessExpressionDeclaration, data: Constraint) - operator fun set(expression: ExpressionDeclaration, data: ConstraintContainer) { + operator fun set(expression: ExpressionDeclaration, data: Constraint) { when (expression) { is IdentifierExpressionDeclaration -> this[expression] = data //is PropertyAccessExpressionDeclaration -> this[expression] = data @@ -51,19 +51,19 @@ interface PropertyOwner { } - operator fun get(name: String) : ConstraintContainer? + operator fun get(name: String) : Constraint? - operator fun get(identifier: IdentifierEntity) : ConstraintContainer? { + operator fun get(identifier: IdentifierEntity) : Constraint? { return this[identifier.value] } - operator fun get(identifierExpression: IdentifierExpressionDeclaration) : ConstraintContainer? { + operator fun get(identifierExpression: IdentifierExpressionDeclaration) : Constraint? { return this[identifierExpression.identifier] } - //operator fun get(propertyAccessExpression: PropertyAccessExpressionDeclaration) : ConstraintContainer? + //operator fun get(propertyAccessExpression: PropertyAccessExpressionDeclaration) : Constraint? - operator fun get(expression: ExpressionDeclaration) : ConstraintContainer? { + operator fun get(expression: ExpressionDeclaration) : Constraint? { return when (expression) { is IdentifierExpressionDeclaration -> this[expression] //is PropertyAccessExpressionDeclaration -> this[expression] diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt new file mode 100644 index 000000000..f70157c90 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt @@ -0,0 +1,22 @@ +package org.jetbrains.dukat.js.type.property_owner + +import org.jetbrains.dukat.js.type.constraint.Constraint + +class Scope : PropertyOwner { + override val propertyNames: Set + get() = properties.keys + + private val properties = LinkedHashMap() + + override fun set(name: String, data: Constraint) { + properties[name] = data + } + + override fun has(name: String): Boolean { + return properties.containsKey(name) + } + + override fun get(name: String): Constraint? { + return properties[name] + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/type/types.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/type/types.kt index 9df6e5264..e3c08b672 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/type/types.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/type/types.kt @@ -3,7 +3,7 @@ package org.jetbrains.dukat.js.type.type import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.tsmodel.types.TypeDeclaration -val unitType = TypeDeclaration( +val voidType = TypeDeclaration( value = IdentifierEntity("Unit"), params = emptyList(), nullable = false From 3d1b89176bf3f290a6c817e15f97d717a20cba86 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Nov 2019 14:55:23 +0100 Subject: [PATCH 046/172] Split up tests --- .../test/data/javascript/class/methods.d.kt | 22 ++++++ .../test/data/javascript/class/methods.d.ts | 14 ++++ .../test/data/javascript/class/static.d.kt | 24 +++++++ .../test/data/javascript/class/static.d.ts | 14 ++++ compiler/test/data/javascript/function.d.kt | 63 ----------------- .../data/javascript/function/function.d.kt | 28 ++++++++ .../data/javascript/function/function.d.ts | 25 +++++++ .../data/javascript/literal/literals.d.kt | 22 ++++++ .../data/javascript/literal/literals.d.ts | 5 ++ .../test/data/javascript/misc/operators.d.kt | 22 ++++++ .../test/data/javascript/misc/operators.d.ts | 12 ++++ .../test/data/javascript/misc/random.d.kt | 25 +++++++ .../{function.d.ts => misc/random.d.ts} | 68 ------------------- .../data/javascript/reference/function.d.kt | 20 ++++++ .../data/javascript/reference/function.d.ts | 8 +++ .../data/javascript/reference/variable.d.kt | 28 ++++++++ .../data/javascript/reference/variable.d.ts | 15 ++++ 17 files changed, 284 insertions(+), 131 deletions(-) create mode 100644 compiler/test/data/javascript/class/methods.d.kt create mode 100644 compiler/test/data/javascript/class/methods.d.ts create mode 100644 compiler/test/data/javascript/class/static.d.kt create mode 100644 compiler/test/data/javascript/class/static.d.ts delete mode 100644 compiler/test/data/javascript/function.d.kt create mode 100644 compiler/test/data/javascript/function/function.d.kt create mode 100644 compiler/test/data/javascript/function/function.d.ts create mode 100644 compiler/test/data/javascript/literal/literals.d.kt create mode 100644 compiler/test/data/javascript/literal/literals.d.ts create mode 100644 compiler/test/data/javascript/misc/operators.d.kt create mode 100644 compiler/test/data/javascript/misc/operators.d.ts create mode 100644 compiler/test/data/javascript/misc/random.d.kt rename compiler/test/data/javascript/{function.d.ts => misc/random.d.ts} (72%) create mode 100644 compiler/test/data/javascript/reference/function.d.kt create mode 100644 compiler/test/data/javascript/reference/function.d.ts create mode 100644 compiler/test/data/javascript/reference/variable.d.kt create mode 100644 compiler/test/data/javascript/reference/variable.d.ts diff --git a/compiler/test/data/javascript/class/methods.d.kt b/compiler/test/data/javascript/class/methods.d.kt new file mode 100644 index 000000000..3ebedd421 --- /dev/null +++ b/compiler/test/data/javascript/class/methods.d.kt @@ -0,0 +1,22 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external open class Literals { + open fun getStringLiteral(): String + open fun getNumberLiteral(): Number + open fun getBooleanLiteral(): Boolean +} \ No newline at end of file diff --git a/compiler/test/data/javascript/class/methods.d.ts b/compiler/test/data/javascript/class/methods.d.ts new file mode 100644 index 000000000..a5ba57b8d --- /dev/null +++ b/compiler/test/data/javascript/class/methods.d.ts @@ -0,0 +1,14 @@ + +class Literals { + getStringLiteral() { + return "text" + } + + getNumberLiteral() { + return 3.141592653 + } + + getBooleanLiteral() { + return false + } +} diff --git a/compiler/test/data/javascript/class/static.d.kt b/compiler/test/data/javascript/class/static.d.kt new file mode 100644 index 000000000..fd3d04bbc --- /dev/null +++ b/compiler/test/data/javascript/class/static.d.kt @@ -0,0 +1,24 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external open class Literals { + companion object { + fun getStringLiteral(): String + fun getNumberLiteral(): Number + fun getBooleanLiteral(): Boolean + } +} \ No newline at end of file diff --git a/compiler/test/data/javascript/class/static.d.ts b/compiler/test/data/javascript/class/static.d.ts new file mode 100644 index 000000000..7d4499769 --- /dev/null +++ b/compiler/test/data/javascript/class/static.d.ts @@ -0,0 +1,14 @@ + +class Literals { + static getStringLiteral() { + return "text" + } + + static getNumberLiteral() { + return 3.141592653 + } + + static getBooleanLiteral() { + return false + } +} diff --git a/compiler/test/data/javascript/function.d.kt b/compiler/test/data/javascript/function.d.kt deleted file mode 100644 index 5ff0a7ac8..000000000 --- a/compiler/test/data/javascript/function.d.kt +++ /dev/null @@ -1,63 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") - -import kotlin.js.* -import kotlin.js.Json -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external var num: Number - -external var bool: Boolean - -external var str: String - -external fun numBinaryFun(a: Number, b: Number): Number - -external fun numBinaryFunWrapper(a: Number, b: Number): Number - -external fun numUnaryFun(a: Number): Number - -external fun numReferenceFun(): Number - -external fun boolBinaryFun(a: Any?, b: Any?): Boolean - -external fun boolUnaryFun(a: Any?): Boolean - -external fun boolReferenceFun(): Boolean - -external fun stringReferenceFun(): String - -external fun anyFun(a: Any?, b: Any?): Any? - -external fun unitFunction() - -external fun typeOf(o: Any?): String - -external fun instanceOfObject(o: Any?): Boolean - -external open class Literals { - companion object { - fun getStringLiteral(): String - fun getNumberLiteral(): Number - fun getBooleanLiteral(): Boolean - } -} - -external open class TestSet { - open fun isElement(obj: Any?): Boolean - open fun isObject(obj: Any?): Boolean - open fun isArray(obj: Any?): Boolean - open fun isArrayLike(collection: Any?): Boolean - open fun keyInObj(key: Any?, obj: Any?): Boolean - open fun negate(predicate: Any?): Boolean -} \ No newline at end of file diff --git a/compiler/test/data/javascript/function/function.d.kt b/compiler/test/data/javascript/function/function.d.kt new file mode 100644 index 000000000..e56b1cf19 --- /dev/null +++ b/compiler/test/data/javascript/function/function.d.kt @@ -0,0 +1,28 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun numBinaryFun(a: Number, b: Number): Number + +external fun numUnaryFun(a: Number): Number + +external fun boolBinaryFun(a: Any?, b: Any?): Boolean + +external fun boolUnaryFun(a: Any?): Boolean + +external fun anyFun(a: Any?, b: Any?): Any? + +external fun unitFunction() \ No newline at end of file diff --git a/compiler/test/data/javascript/function/function.d.ts b/compiler/test/data/javascript/function/function.d.ts new file mode 100644 index 000000000..cc26d818c --- /dev/null +++ b/compiler/test/data/javascript/function/function.d.ts @@ -0,0 +1,25 @@ +function numBinaryFun(a, b) { + return a - b +} + +function numUnaryFun(a) { + var b = a + a = "text" + return b++ +} + +function boolBinaryFun(a, b) { + return a == b +} + +function boolUnaryFun(a) { + return !a +} + +function anyFun(a, b) { + return a + b +} + +function unitFunction() { + return; +} \ No newline at end of file diff --git a/compiler/test/data/javascript/literal/literals.d.kt b/compiler/test/data/javascript/literal/literals.d.kt new file mode 100644 index 000000000..ea713ca4e --- /dev/null +++ b/compiler/test/data/javascript/literal/literals.d.kt @@ -0,0 +1,22 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external var num: Number + +external var bool: Boolean + +external var str: String \ No newline at end of file diff --git a/compiler/test/data/javascript/literal/literals.d.ts b/compiler/test/data/javascript/literal/literals.d.ts new file mode 100644 index 000000000..577116159 --- /dev/null +++ b/compiler/test/data/javascript/literal/literals.d.ts @@ -0,0 +1,5 @@ +var num, bool, str; + +num = 3; +bool = true; +str = "text"; \ No newline at end of file diff --git a/compiler/test/data/javascript/misc/operators.d.kt b/compiler/test/data/javascript/misc/operators.d.kt new file mode 100644 index 000000000..efca584a4 --- /dev/null +++ b/compiler/test/data/javascript/misc/operators.d.kt @@ -0,0 +1,22 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun typeOf(o: Any?): String + +external fun instanceOfObject(o: Any?): Boolean + +external fun keyInObj(key: Any?, obj: Any?): Boolean \ No newline at end of file diff --git a/compiler/test/data/javascript/misc/operators.d.ts b/compiler/test/data/javascript/misc/operators.d.ts new file mode 100644 index 000000000..b10dd292b --- /dev/null +++ b/compiler/test/data/javascript/misc/operators.d.ts @@ -0,0 +1,12 @@ + +function typeOf(o) { + return typeof o +} + +function instanceOfObject(o) { + return o instanceof Object +} + +function keyInObj(key, obj) { + return key in obj; +} diff --git a/compiler/test/data/javascript/misc/random.d.kt b/compiler/test/data/javascript/misc/random.d.kt new file mode 100644 index 000000000..913f5b968 --- /dev/null +++ b/compiler/test/data/javascript/misc/random.d.kt @@ -0,0 +1,25 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external open class TestSet { + open fun isElement(obj: Any?): Boolean + open fun isObject(obj: Any?): Boolean + open fun isArray(obj: Any?): Boolean + open fun isArrayLike(collection: Any?): Boolean + open fun keyInObj(key: Any?, obj: Any?): Boolean + open fun negate(predicate: Any?): Boolean +} \ No newline at end of file diff --git a/compiler/test/data/javascript/function.d.ts b/compiler/test/data/javascript/misc/random.d.ts similarity index 72% rename from compiler/test/data/javascript/function.d.ts rename to compiler/test/data/javascript/misc/random.d.ts index 3e1d2c283..c7ad91f3e 100644 --- a/compiler/test/data/javascript/function.d.ts +++ b/compiler/test/data/javascript/misc/random.d.ts @@ -1,71 +1,3 @@ -var num = 3 -var bool = true -var str = "text" - -function numBinaryFun(a, b) { - return a - b -} - -function numBinaryFunWrapper(a, b) { - return numBinaryFun(a, b) -} - -function numUnaryFun(a) { - var b = a - a = "text" - return b++ -} - -function numReferenceFun() { - return num -} - -function boolBinaryFun(a, b) { - return a == b -} - -function boolUnaryFun(a) { - return !a -} - -function boolReferenceFun() { - return bool -} - -function stringReferenceFun() { - return str -} - -function anyFun(a, b) { - return a + b -} - -function unitFunction() { - return; -} - -function typeOf(o) { - return typeof o -} - -function instanceOfObject(o) { - return o instanceof Object -} - -class Literals { - static getStringLiteral() { - return "text" - } - - static getNumberLiteral() { - return 3.141592653 - } - - static getBooleanLiteral() { - return false - } -} - class TestSet { isElement(obj) { return !!(obj && obj.nodeType === 1); diff --git a/compiler/test/data/javascript/reference/function.d.kt b/compiler/test/data/javascript/reference/function.d.kt new file mode 100644 index 000000000..2e7da8964 --- /dev/null +++ b/compiler/test/data/javascript/reference/function.d.kt @@ -0,0 +1,20 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun numBinaryFun(a: Number, b: Number): Number + +external fun numBinaryFunWrapper(a: Number, b: Number): Number \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/function.d.ts b/compiler/test/data/javascript/reference/function.d.ts new file mode 100644 index 000000000..fd4663c8b --- /dev/null +++ b/compiler/test/data/javascript/reference/function.d.ts @@ -0,0 +1,8 @@ + +function numBinaryFun(a, b) { + return a - b +} + +function numBinaryFunWrapper(a, b) { + return numBinaryFun(a, b) +} diff --git a/compiler/test/data/javascript/reference/variable.d.kt b/compiler/test/data/javascript/reference/variable.d.kt new file mode 100644 index 000000000..5524bf8e2 --- /dev/null +++ b/compiler/test/data/javascript/reference/variable.d.kt @@ -0,0 +1,28 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external var num: Number + +external var bool: Boolean + +external var str: String + +external fun numReferenceFun(): Number + +external fun boolReferenceFun(): Boolean + +external fun stringReferenceFun(): String \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/variable.d.ts b/compiler/test/data/javascript/reference/variable.d.ts new file mode 100644 index 000000000..c32cb4aa6 --- /dev/null +++ b/compiler/test/data/javascript/reference/variable.d.ts @@ -0,0 +1,15 @@ +var num = 3 +var bool = true +var str = "text" + +function numReferenceFun() { + return num +} + +function boolReferenceFun() { + return bool +} + +function stringReferenceFun() { + return str +} \ No newline at end of file From d9b1ebf2871b23cfa6fd139bccc174f202acb976 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Nov 2019 16:08:11 +0100 Subject: [PATCH 047/172] Keep track of types through property access --- .../data/javascript/class/memberAccess.d.kt | 30 ++++++++++++++++++ .../data/javascript/class/memberAccess.d.ts | 18 +++++++++++ .../javascript/class/memberModification.d.kt | 30 ++++++++++++++++++ .../javascript/class/memberModification.d.ts | 21 +++++++++++++ .../dukat/js/type/analysis/expression.kt | 2 ++ .../constraint/properties/ClassConstraint.kt | 10 ++---- .../properties/FunctionConstraint.kt | 2 +- .../constraint/properties/ObjectConstraint.kt | 10 ++---- .../properties/PropertyOwnerConstraint.kt | 6 ++-- .../js/type/property_owner/PropertyOwner.kt | 31 ++++++++++++++----- .../dukat/js/type/property_owner/Scope.kt | 4 --- 11 files changed, 132 insertions(+), 32 deletions(-) create mode 100644 compiler/test/data/javascript/class/memberAccess.d.kt create mode 100644 compiler/test/data/javascript/class/memberAccess.d.ts create mode 100644 compiler/test/data/javascript/class/memberModification.d.kt create mode 100644 compiler/test/data/javascript/class/memberModification.d.ts diff --git a/compiler/test/data/javascript/class/memberAccess.d.kt b/compiler/test/data/javascript/class/memberAccess.d.kt new file mode 100644 index 000000000..0a49ef527 --- /dev/null +++ b/compiler/test/data/javascript/class/memberAccess.d.kt @@ -0,0 +1,30 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external open class Literals { + companion object { + fun getStringLiteral(): String + fun getNumberLiteral(): Number + fun getBooleanLiteral(): Boolean + } +} + +external var str: String + +external var num: Number + +external var bool: Boolean \ No newline at end of file diff --git a/compiler/test/data/javascript/class/memberAccess.d.ts b/compiler/test/data/javascript/class/memberAccess.d.ts new file mode 100644 index 000000000..3032fd088 --- /dev/null +++ b/compiler/test/data/javascript/class/memberAccess.d.ts @@ -0,0 +1,18 @@ + +class Literals { + static getStringLiteral() { + return "text" + } + + static getNumberLiteral() { + return 3.141592653 + } + + static getBooleanLiteral() { + return false + } +} + +var str = Literals.getStringLiteral() +var num = Literals.getNumberLiteral() +var bool = Literals.getBooleanLiteral() \ No newline at end of file diff --git a/compiler/test/data/javascript/class/memberModification.d.kt b/compiler/test/data/javascript/class/memberModification.d.kt new file mode 100644 index 000000000..9a0a3ee5f --- /dev/null +++ b/compiler/test/data/javascript/class/memberModification.d.kt @@ -0,0 +1,30 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external open class ModifiedLiterals { + companion object { + fun getStringLiteral(): Number + fun getNumberLiteral(): Number + fun getBooleanLiteral(): Number + } +} + +external var falseStr: Number + +external var trueNum: Number + +external var falseBool: Number \ No newline at end of file diff --git a/compiler/test/data/javascript/class/memberModification.d.ts b/compiler/test/data/javascript/class/memberModification.d.ts new file mode 100644 index 000000000..6396effdf --- /dev/null +++ b/compiler/test/data/javascript/class/memberModification.d.ts @@ -0,0 +1,21 @@ + +class ModifiedLiterals { + static getStringLiteral() { + return "text" + } + + static getNumberLiteral() { + return 3.141592653 + } + + static getBooleanLiteral() { + return false + } +} + +ModifiedLiterals.getStringLiteral = ModifiedLiterals.getNumberLiteral +ModifiedLiterals.getBooleanLiteral = ModifiedLiterals.getNumberLiteral + +var falseStr = ModifiedLiterals.getStringLiteral() +var trueNum = ModifiedLiterals.getNumberLiteral() +var falseBool = ModifiedLiterals.getBooleanLiteral() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 23ad95b91..8b414e615 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -16,6 +16,7 @@ import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.CallExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.TypeOfExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration @@ -118,6 +119,7 @@ fun LiteralExpressionDeclaration.calculateConstraints() : Constraint { fun ExpressionDeclaration?.calculateConstraints(owner: PropertyOwner) : Constraint { return when (this) { is IdentifierExpressionDeclaration -> owner[this] ?: ReferenceConstraint(this.identifier) + is PropertyAccessExpressionDeclaration -> owner[this] ?: CompositeConstraint() //TODO replace this with a reference constraint (of some sort) is BinaryExpressionDeclaration -> this.calculateConstraints(owner) is UnaryExpressionDeclaration -> this.calculateConstraints(owner) is TypeOfExpressionDeclaration -> this.calculateConstraints(owner) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt index 0440e8f56..dabb7ba03 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt @@ -1,8 +1,6 @@ package org.jetbrains.dukat.js.type.constraint.properties -import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class ClassConstraint(val prototype: ObjectConstraint = ObjectConstraint()) : PropertyOwnerConstraint { @@ -15,16 +13,12 @@ class ClassConstraint(val prototype: ObjectConstraint = ObjectConstraint()) : Pr staticMembers[name] = data } - override fun has(name: String): Boolean { - return staticMembers.containsKey(name) - } - override fun get(name: String): Constraint? { return staticMembers[name] } - override fun resolve(owner: PropertyOwner): Constraint { - val resolvedConstraint = ClassConstraint(prototype.resolve(owner) as ObjectConstraint) + override fun resolve(owner: PropertyOwner): ClassConstraint { + val resolvedConstraint = ClassConstraint(prototype = prototype.resolve(owner)) propertyNames.forEach { resolvedConstraint[it] = this[it]!!.resolve(owner) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt index 8e4fe8c03..dd9062a2e 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt @@ -8,7 +8,7 @@ class FunctionConstraint( val returnConstraints: Constraint, val parameterConstraints: List> ) : ImmutableConstraint { //TODO make property owner (since functions technically are, in javascript) - override fun resolve(owner: PropertyOwner): Constraint { + override fun resolve(owner: PropertyOwner): FunctionConstraint { return FunctionConstraint( returnConstraints.resolve(owner), parameterConstraints.map { (name, constraint) -> name to constraint.resolve(owner) } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt index 2000d6e3e..04354fe41 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt @@ -2,6 +2,7 @@ package org.jetbrains.dukat.js.type.constraint.properties import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaration class ObjectConstraint( private val instantiatedClass: ClassConstraint? = null @@ -22,19 +23,14 @@ class ObjectConstraint( properties[name] = data } - override fun has(name: String): Boolean { - return properties.containsKey(name) || instantiatedClass?.prototype?.has(name) == true - } - override fun get(name: String): Constraint? { return when { properties.containsKey(name) -> properties[name] - instantiatedClass?.prototype?.has(name) == true -> instantiatedClass.prototype[name] - else -> null + else -> instantiatedClass?.prototype?.get(name) } } - override fun resolve(owner: PropertyOwner): Constraint { + override fun resolve(owner: PropertyOwner): ObjectConstraint { val resolvedConstraint = ObjectConstraint() propertyNames.forEach { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt index c7765b017..1f26b5c86 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt @@ -1,8 +1,6 @@ package org.jetbrains.dukat.js.type.constraint.properties -import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -interface PropertyOwnerConstraint : PropertyOwner, Constraint { - override fun plusAssign(other: Constraint) {} -} \ No newline at end of file +interface PropertyOwnerConstraint : PropertyOwner, ImmutableConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt index c3da3b7bb..2c4b5e151 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt @@ -4,6 +4,7 @@ import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration interface PropertyOwner { @@ -19,17 +20,23 @@ interface PropertyOwner { this[identifierExpression.identifier] = data } - //operator fun set(propertyAccessExpression: PropertyAccessExpressionDeclaration, data: Constraint) + operator fun set(propertyAccessExpression: PropertyAccessExpressionDeclaration, data: Constraint) { + val base = this[propertyAccessExpression.expression] + + if (base is PropertyOwner) { + base[propertyAccessExpression.name] = data + } + } operator fun set(expression: ExpressionDeclaration, data: Constraint) { when (expression) { is IdentifierExpressionDeclaration -> this[expression] = data - //is PropertyAccessExpressionDeclaration -> this[expression] = data + is PropertyAccessExpressionDeclaration -> this[expression] = data else -> raiseConcern("Cannot set variable described by expression of type <${expression::class}>") { } } } - + /* fun has(name: String) : Boolean fun has(identifier: IdentifierEntity) : Boolean { @@ -40,16 +47,16 @@ interface PropertyOwner { return has(identifierExpression.identifier) } - //fun has(propertyAccessExpression: PropertyAccessExpressionDeclaration) : Boolean + fun has(propertyAccessExpression: PropertyAccessExpressionDeclaration) : Boolean fun has(expression: ExpressionDeclaration) : Boolean { return when (expression) { is IdentifierExpressionDeclaration -> has(expression) - //is PropertyAccessExpressionDeclaration -> has(expression) + is PropertyAccessExpressionDeclaration -> has(expression) else -> raiseConcern("Cannot get variable described by expression of type <${expression::class}>") { false } } } - + */ operator fun get(name: String) : Constraint? @@ -61,12 +68,20 @@ interface PropertyOwner { return this[identifierExpression.identifier] } - //operator fun get(propertyAccessExpression: PropertyAccessExpressionDeclaration) : Constraint? + operator fun get(propertyAccessExpression: PropertyAccessExpressionDeclaration) : Constraint? { + val base = this[propertyAccessExpression.expression] + + return if (base is PropertyOwner) { + base[propertyAccessExpression.name] + } else { + null + } + } operator fun get(expression: ExpressionDeclaration) : Constraint? { return when (expression) { is IdentifierExpressionDeclaration -> this[expression] - //is PropertyAccessExpressionDeclaration -> this[expression] + is PropertyAccessExpressionDeclaration -> this[expression] else -> raiseConcern("Cannot get variable described by expression of type <${expression::class}>") { null } } } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt index f70157c90..819e48fc1 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt @@ -12,10 +12,6 @@ class Scope : PropertyOwner { properties[name] = data } - override fun has(name: String): Boolean { - return properties.containsKey(name) - } - override fun get(name: String): Constraint? { return properties[name] } From 3338ba4fa4db1348c234c32c9ae1bcfc760a474d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Nov 2019 17:34:13 +0100 Subject: [PATCH 048/172] Allow access to properties in references outside of scope --- .../composite/ReferenceConstraint.kt | 49 +++++++++++++++++-- .../dukat/js/type/property_owner/Scope.kt | 6 ++- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/ReferenceConstraint.kt index ec892f4d3..e8029107c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/ReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/ReferenceConstraint.kt @@ -2,13 +2,54 @@ package org.jetbrains.dukat.js.type.constraint.composite import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint +import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.panic.raiseConcern data class ReferenceConstraint( - val identifier: IdentifierEntity -) : ImmutableConstraint { //TODO make modifiable + val identifier: IdentifierEntity, + val parent: ReferenceConstraint? = null +) : PropertyOwnerConstraint { + override val propertyNames: Set + get() = raiseConcern("Properties of a reference should never be listed.") { emptySet() } + + private val modifiedProperties = LinkedHashMap() + + override fun set(name: String, data: Constraint) { + modifiedProperties[name] = data + } + + override fun get(name: String): Constraint { + return modifiedProperties[name] ?: ReferenceConstraint(IdentifierEntity(name), this) + } + override fun resolve(owner: PropertyOwner): Constraint { - return owner[identifier]?.resolve(owner) ?: this + val referenceOwner = if (parent != null) { + val resolvedParent = parent.resolve(owner) + + if(resolvedParent is PropertyOwner) { + resolvedParent + } else { + raiseConcern("Accessing property of non-property-owner") { } + return CompositeConstraint() + } + } else { + owner + } + + val dereferencedConstraint = referenceOwner[identifier] + + return if (dereferencedConstraint != null && dereferencedConstraint !is ReferenceConstraint) { + if(dereferencedConstraint is PropertyOwner) { + modifiedProperties.forEach { (name, constraint) -> + //TODO take composite constraints into account here + dereferencedConstraint[name] = constraint + } + } + + dereferencedConstraint.resolve(referenceOwner) + } else { + this + } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt index 819e48fc1..b2ac6d36e 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt @@ -1,6 +1,8 @@ package org.jetbrains.dukat.js.type.property_owner +import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.composite.ReferenceConstraint class Scope : PropertyOwner { override val propertyNames: Set @@ -12,7 +14,7 @@ class Scope : PropertyOwner { properties[name] = data } - override fun get(name: String): Constraint? { - return properties[name] + override fun get(name: String): Constraint { + return properties[name] ?: ReferenceConstraint(IdentifierEntity(name)) } } \ No newline at end of file From c92a0361f9e8b050d13462f64658350a2b997a8d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Nov 2019 17:34:53 +0100 Subject: [PATCH 049/172] Add tests for properties in references --- .../data/javascript/reference/property.d.kt | 24 +++++++++++++++++++ .../data/javascript/reference/property.d.ts | 9 +++++++ .../data/javascript/reference/undefined.d.kt | 18 ++++++++++++++ .../data/javascript/reference/undefined.d.ts | 3 +++ 4 files changed, 54 insertions(+) create mode 100644 compiler/test/data/javascript/reference/property.d.kt create mode 100644 compiler/test/data/javascript/reference/property.d.ts create mode 100644 compiler/test/data/javascript/reference/undefined.d.kt create mode 100644 compiler/test/data/javascript/reference/undefined.d.ts diff --git a/compiler/test/data/javascript/reference/property.d.kt b/compiler/test/data/javascript/reference/property.d.kt new file mode 100644 index 000000000..18354a35a --- /dev/null +++ b/compiler/test/data/javascript/reference/property.d.kt @@ -0,0 +1,24 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external open class PropertyOwner { + companion object { + fun property(): String + } +} + +external fun wrapperFun(): String \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/property.d.ts b/compiler/test/data/javascript/reference/property.d.ts new file mode 100644 index 000000000..8380e6221 --- /dev/null +++ b/compiler/test/data/javascript/reference/property.d.ts @@ -0,0 +1,9 @@ +class PropertyOwner { + static property() { + return "Hello, world!" + } +} + +function wrapperFun() { + return PropertyOwner.property() +} \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/undefined.d.kt b/compiler/test/data/javascript/reference/undefined.d.kt new file mode 100644 index 000000000..3662d5832 --- /dev/null +++ b/compiler/test/data/javascript/reference/undefined.d.kt @@ -0,0 +1,18 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun undefReferenceFun() \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/undefined.d.ts b/compiler/test/data/javascript/reference/undefined.d.ts new file mode 100644 index 000000000..5ccef2f12 --- /dev/null +++ b/compiler/test/data/javascript/reference/undefined.d.ts @@ -0,0 +1,3 @@ +function undefReferenceFun() { + return PropertyOwner.property() +} \ No newline at end of file From 8347277e7cda366cdadd41ba2830f17cc0ae9dc5 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2019 10:22:56 +0100 Subject: [PATCH 050/172] Extract unit functions into their own test --- .../data/javascript/function/function.d.kt | 4 +--- .../data/javascript/function/function.d.ts | 4 ---- .../test/data/javascript/function/unit.d.kt | 20 +++++++++++++++++++ .../test/data/javascript/function/unit.d.ts | 8 ++++++++ 4 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 compiler/test/data/javascript/function/unit.d.kt create mode 100644 compiler/test/data/javascript/function/unit.d.ts diff --git a/compiler/test/data/javascript/function/function.d.kt b/compiler/test/data/javascript/function/function.d.kt index e56b1cf19..fe3030b85 100644 --- a/compiler/test/data/javascript/function/function.d.kt +++ b/compiler/test/data/javascript/function/function.d.kt @@ -23,6 +23,4 @@ external fun boolBinaryFun(a: Any?, b: Any?): Boolean external fun boolUnaryFun(a: Any?): Boolean -external fun anyFun(a: Any?, b: Any?): Any? - -external fun unitFunction() \ No newline at end of file +external fun anyFun(a: Any?, b: Any?): Any? \ No newline at end of file diff --git a/compiler/test/data/javascript/function/function.d.ts b/compiler/test/data/javascript/function/function.d.ts index cc26d818c..2e8f90fdb 100644 --- a/compiler/test/data/javascript/function/function.d.ts +++ b/compiler/test/data/javascript/function/function.d.ts @@ -18,8 +18,4 @@ function boolUnaryFun(a) { function anyFun(a, b) { return a + b -} - -function unitFunction() { - return; } \ No newline at end of file diff --git a/compiler/test/data/javascript/function/unit.d.kt b/compiler/test/data/javascript/function/unit.d.kt new file mode 100644 index 000000000..cb331301d --- /dev/null +++ b/compiler/test/data/javascript/function/unit.d.kt @@ -0,0 +1,20 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun emptyReturnFunction() + +external fun unitFunction() \ No newline at end of file diff --git a/compiler/test/data/javascript/function/unit.d.ts b/compiler/test/data/javascript/function/unit.d.ts new file mode 100644 index 000000000..769af0093 --- /dev/null +++ b/compiler/test/data/javascript/function/unit.d.ts @@ -0,0 +1,8 @@ +function emptyReturnFunction() { + console.log("Nothing is happening!") + return; +} + +function unitFunction() { + console.log("Nothing is happening!") +} \ No newline at end of file From d7b3f0feaaa05923b0a1db7b6ef0ce40c9439892 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2019 10:26:20 +0100 Subject: [PATCH 051/172] Make extension function for calculating constraints for expressions not take null --- .../src/org/jetbrains/dukat/js/type/analysis/expression.kt | 5 ++--- .../org/jetbrains/dukat/js/type/analysis/introduceTypes.kt | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 8b414e615..20b78fc8f 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -116,7 +116,7 @@ fun LiteralExpressionDeclaration.calculateConstraints() : Constraint { } } -fun ExpressionDeclaration?.calculateConstraints(owner: PropertyOwner) : Constraint { +fun ExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { return when (this) { is IdentifierExpressionDeclaration -> owner[this] ?: ReferenceConstraint(this.identifier) is PropertyAccessExpressionDeclaration -> owner[this] ?: CompositeConstraint() //TODO replace this with a reference constraint (of some sort) @@ -125,7 +125,6 @@ fun ExpressionDeclaration?.calculateConstraints(owner: PropertyOwner) : Constrai is TypeOfExpressionDeclaration -> this.calculateConstraints(owner) is CallExpressionDeclaration -> this.calculateConstraints(owner) is LiteralExpressionDeclaration -> this.calculateConstraints() - null -> VoidTypeConstraint - else -> CompositeConstraint() + else -> CompositeConstraint(NoTypeConstraint) } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index 97ebe7932..744d4df14 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -86,7 +86,7 @@ fun BlockDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { } fun VariableDeclaration.addTo(owner: PropertyOwner) { - owner[name] = initializer.calculateConstraints(owner) + owner[name] = initializer?.calculateConstraints(owner) ?: VoidTypeConstraint } fun ExpressionStatementDeclaration.calculateConstraints(owner: PropertyOwner) { @@ -94,7 +94,7 @@ fun ExpressionStatementDeclaration.calculateConstraints(owner: PropertyOwner) { } fun ReturnStatementDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { - return expression.calculateConstraints(owner) + return expression?.calculateConstraints(owner) ?: VoidTypeConstraint } fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint? { From 439abd60b7afa3d3055cbeeea98823e15108f92f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2019 10:27:02 +0100 Subject: [PATCH 052/172] Add TODO for CallResultConstraint, to make it mutable --- .../js/type/constraint/immutable/call/CallResultConstraint.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallResultConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallResultConstraint.kt index b19a3a1ea..d649f2832 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallResultConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallResultConstraint.kt @@ -1,7 +1,6 @@ package org.jetbrains.dukat.js.type.constraint.immutable.call import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner @@ -9,7 +8,7 @@ import org.jetbrains.dukat.js.type.property_owner.PropertyOwner data class CallResultConstraint( val callTarget: Constraint, val arguments: List -) : ImmutableConstraint { +) : ImmutableConstraint { //TODO treat this similarly to a reference constraint override fun resolve(owner: PropertyOwner): Constraint { val functionConstraint = callTarget.getResolvedFunctionConstraint(owner) From 656d989843efb25bd7ee6a2129b658aeaccc8ec7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2019 16:41:14 +0100 Subject: [PATCH 053/172] Support object literal expressions --- typescript/ts-converter/src/AstConverter.ts | 12 +- .../src/ast/AstExpressionConverter.ts | 153 +++++++++++++----- .../src/ast/AstExpressionFactory.ts | 51 +++++- typescript/ts-converter/src/ast/ast.ts | 2 + .../ts-model-proto/src/Declarations.proto | 19 ++- .../dukat/tsmodel/FunctionDeclaration.kt | 3 +- .../obj/ObjectLiteralExpressionDeclaration.kt | 7 + .../literal/obj/ObjectMemberDeclaration.kt | 3 + .../literal/obj/ObjectPropertyDeclaration.kt | 8 + .../dukat/tsmodel/factory/convertProtobuf.kt | 22 +++ 10 files changed, 235 insertions(+), 45 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectLiteralExpressionDeclaration.kt create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectMemberDeclaration.kt create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectPropertyDeclaration.kt diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index ea558699f..99d2e0e94 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -42,6 +42,8 @@ export class AstConverter { private resources = new ResourceFetcher(this.sourceFileFetcher, this.sourceName); + private astExpressionConverter = new AstExpressionConverter(this); + private libVisitor = new LibraryDeclarationsVisitor( this.typeChecker ); @@ -327,7 +329,7 @@ export class AstConverter { return this.astFactory.createFunctionDeclarationAsMember(name, parameters, type, typeParams, modifiers, body, "__NO_UID__"); } - private createTypeDeclaration(value: string, params: Array = [], typeReference: string | null = null): TypeDeclaration { + createTypeDeclaration(value: string, params: Array = [], typeReference: string | null = null): TypeDeclaration { return this.astFactory.createTypeReferenceDeclarationAsParamValue(this.astFactory.createIdentifierDeclarationAsNameEntity(value), params, null); } @@ -469,7 +471,7 @@ export class AstConverter { convertParameterDeclaration(param: ts.ParameterDeclaration, index: number): ParameterDeclaration { let initializer: Expression | null = null; if (param.initializer != null) { - initializer = AstExpressionConverter.convertUnknownExpression(param.initializer) + initializer = this.astExpressionConverter.convertUnknownExpression(param.initializer) } let paramType = this.convertType(param.type); @@ -811,18 +813,18 @@ export class AstConverter { declaration.name.getText(), this.convertType(declaration.type), this.convertModifiers(statement.modifiers), - declaration.initializer == null ? null : AstExpressionConverter.convertExpression(declaration.initializer), + declaration.initializer == null ? null : this.astExpressionConverter.convertExpression(declaration.initializer), this.exportContext.getUID(declaration) )); } } else if (ts.isExpressionStatement(statement)) { res.push(this.astFactory.createExpressionStatement( - AstExpressionConverter.convertExpression(statement.expression) + this.astExpressionConverter.convertExpression(statement.expression) )); } else if (ts.isReturnStatement(statement)) { let expression : Expression | null = null; if (statement.expression) { - expression = AstExpressionConverter.convertExpression(statement.expression) + expression = this.astExpressionConverter.convertExpression(statement.expression) } res.push(this.astFactory.createReturnStatement( diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index ce24b65e3..db9926db8 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -1,63 +1,89 @@ import * as ts from "typescript-services-api"; -import {Expression, IdentifierEntity, NameEntity} from "./ast"; +import { + Block, + Expression, FunctionDeclaration, + IdentifierEntity, + MemberDeclaration, ModifierDeclaration, + NameEntity, + ObjectMember, + ParameterDeclaration, ParameterValue, + TypeParameter +} from "./ast"; import {AstExpressionFactory} from "./AstExpressionFactory"; -import {LeftHandSideExpression, NodeArray, TypeNode} from "../../.tsdeclarations/tsserverlibrary"; +import {AstConverter} from "../AstConverter"; export class AstExpressionConverter { - static createBinaryExpression(left: Expression, operator: string, right: Expression): Expression { + constructor( + private astConverter: AstConverter + ) { + } + + createBinaryExpression(left: Expression, operator: string, right: Expression): Expression { return AstExpressionFactory.createBinaryExpressionDeclarationAsExpression(left, operator, right); } - static createUnaryExpression(operand: Expression, operator: string, isPrefix: boolean) { + createUnaryExpression(operand: Expression, operator: string, isPrefix: boolean) { return AstExpressionFactory.createUnaryExpressionDeclarationAsExpression(operand, operator, isPrefix); } - static createTypeOfExpression(expression: Expression) { + createTypeOfExpression(expression: Expression) { return AstExpressionFactory.createTypeOfExpressionDeclarationAsExpression(expression); } - static createCallExpression(expression: Expression, args: Array) { + createCallExpression(expression: Expression, args: Array) { return AstExpressionFactory.createCallExpressionDeclarationAsExpression(expression, args); } - static createPropertyAccessExpression(expression: Expression, name: IdentifierEntity) { + createPropertyAccessExpression(expression: Expression, name: IdentifierEntity) { return AstExpressionFactory.createPropertyAccessExpressionDeclarationAsExpression(expression, name); } - static createElementAccessExpression(expression: Expression, argumentExpression: Expression) { + createElementAccessExpression(expression: Expression, argumentExpression: Expression) { return AstExpressionFactory.createElementAccessExpressionDeclarationAsExpression(expression, argumentExpression); } - static createNameExpression(name: NameEntity): Expression { + createNameExpression(name: NameEntity): Expression { return AstExpressionFactory.createNameExpressionDeclarationAsExpression(name) } - static createNumericLiteralExpression(value: string): Expression { + createNumericLiteralExpression(value: string): Expression { return AstExpressionFactory.createNumericLiteralDeclarationAsExpression(value); } - static createBigIntLiteralExpression(value: string): Expression { + createBigIntLiteralExpression(value: string): Expression { return AstExpressionFactory.createBigIntLiteralDeclarationAsExpression(value); } - static createStringLiteralExpression(value: string): Expression { + createStringLiteralExpression(value: string): Expression { return AstExpressionFactory.createStringLiteralDeclarationAsExpression(value); } - static createBooleanLiteralExpression(value: boolean): Expression { + createBooleanLiteralExpression(value: boolean): Expression { return AstExpressionFactory.createBooleanLiteralDeclarationAsExpression(value); } - static createRegExLiteralExpression(value: string): Expression { + createObjectLiteralExpression(members: Array): Expression { + return AstExpressionFactory.createObjectLiteralDeclarationAsExpression(members); + } + + createRegExLiteralExpression(value: string): Expression { return AstExpressionFactory.createRegExLiteralDeclarationAsExpression(value); } - static createUnknownExpression(value: string): Expression { + createUnknownExpression(value: string): Expression { return AstExpressionFactory.createUnknownExpressionDeclarationAsExpression(value); } + private createObjectProperty(name: string, initializer: Expression | null): ObjectMember { + return AstExpressionFactory.createObjectProperty(name, initializer); + } + + private createObjectMethod(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, body: Block | null): ObjectMember { + return AstExpressionFactory.createObjectMethod(name, parameters, type, typeParams, modifiers, body); + } + - static convertBinaryExpression(expression: ts.BinaryExpression): Expression { + convertBinaryExpression(expression: ts.BinaryExpression): Expression { return this.createBinaryExpression( this.convertExpression(expression.left), ts.tokenToString(expression.operatorToken.kind), @@ -65,7 +91,7 @@ export class AstExpressionConverter { ) } - static convertPrefixUnaryExpression(expression: ts.PrefixUnaryExpression): Expression { + convertPrefixUnaryExpression(expression: ts.PrefixUnaryExpression): Expression { return this.createUnaryExpression( this.convertExpression(expression.operand), ts.tokenToString(expression.operator), @@ -73,7 +99,7 @@ export class AstExpressionConverter { ) } - static convertPostfixUnaryExpression(expression: ts.PostfixUnaryExpression): Expression { + convertPostfixUnaryExpression(expression: ts.PostfixUnaryExpression): Expression { return this.createUnaryExpression( this.convertExpression(expression.operand), ts.tokenToString(expression.operator), @@ -81,40 +107,40 @@ export class AstExpressionConverter { ) } - static convertTypeOfExpression(expression: ts.TypeOfExpression): Expression { + convertTypeOfExpression(expression: ts.TypeOfExpression): Expression { return this.createTypeOfExpression( this.convertExpression(expression.expression), ) } - static convertCallExpression(expression: ts.CallExpression): Expression { + convertCallExpression(expression: ts.CallExpression): Expression { return this.createCallExpression( this.convertExpression(expression.expression), expression.arguments.map(arg => this.convertExpression(arg)) ) } - static convertPropertyAccessExpression(expression: ts.PropertyAccessExpression): Expression { + convertPropertyAccessExpression(expression: ts.PropertyAccessExpression): Expression { return this.createPropertyAccessExpression( this.convertExpression(expression.expression), AstExpressionFactory.createIdentifier(expression.name.getText()) ) } - static convertElementAccessExpression(expression: ts.ElementAccessExpression): Expression { + convertElementAccessExpression(expression: ts.ElementAccessExpression): Expression { return this.createElementAccessExpression( this.convertExpression(expression.expression), this.convertExpression(expression.argumentExpression) ) } - static convertNameExpression(name: ts.EntityName): Expression { + convertNameExpression(name: ts.EntityName): Expression { return this.createNameExpression( this.convertEntityName(name) ) } - static convertEntityName(entityName: ts.EntityName): NameEntity { + convertEntityName(entityName: ts.EntityName): NameEntity { if (ts.isQualifiedName(entityName)) { return AstExpressionFactory.createQualifierAsNameEntity( this.convertEntityName(entityName.left), @@ -127,23 +153,76 @@ export class AstExpressionConverter { } } - static convertNumericLiteralExpression(expression: ts.Expression): Expression { - return this.createNumericLiteralExpression(expression.getText()) + convertNumericLiteralExpression(literal: ts.NumericLiteral): Expression { + return this.createNumericLiteralExpression(literal.getText()) + } + + convertBigIntLiteralExpression(literal: ts.BigIntLiteral): Expression { + return this.createBigIntLiteralExpression(literal.getText()) } - static convertBigIntLiteralExpression(expression: ts.Expression): Expression { - return this.createBigIntLiteralExpression(expression.getText()) + convertStringLiteralExpression(literal: ts.StringLiteral): Expression { + return this.createStringLiteralExpression(literal.getText()) + } + + private convertObjectProperty(name: ts.PropertyName, value: ts.Expression): ObjectMember | null { + let convertedName = this.astConverter.convertName(name); + + if (convertedName) { + return this.createObjectProperty(convertedName, this.convertExpression(value)) + } else { + return null; + } + } + + private convertObjectMethod(method: ts.MethodDeclaration): ObjectMember | null { + let convertedName = this.astConverter.convertName(method.name); + + if (convertedName) { + return this.createObjectMethod( + convertedName, + method.parameters.map((param, count) => this.astConverter.convertParameterDeclaration(param, count)), + method.type ? this.astConverter.convertType(method.type) : this.astConverter.createTypeDeclaration("Unit"), + this.astConverter.convertTypeParams(method.typeParameters), + this.astConverter.convertModifiers(method.modifiers), + this.astConverter.convertBlock(method.body), + ); + } else { + return null; + } } - static convertStringLiteralExpression(expression: ts.Expression): Expression { - return this.createStringLiteralExpression(expression.getText()) + convertObjectLiteralExpression(literal: ts.ObjectLiteralExpression): Expression { + let members: Array = []; + + literal.properties.forEach(member => { + let objectMember: ObjectMember | null = null; + + if (ts.isPropertyAssignment(member)) { + objectMember = this.convertObjectProperty(member.name, member.initializer); + } else if (ts.isShorthandPropertyAssignment(member)) { + objectMember = this.convertObjectProperty(member.name, member.name); + } else if (ts.isMethodDeclaration(member)) { + objectMember = this.convertObjectMethod(member) + } else if (ts.isSpreadAssignment(member)) { + //TODO support spread assignments + } else if (ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)) { + //TODO support accessor declarations + } + + if (objectMember) { + members.push(objectMember); + } + }); + + return this.createObjectLiteralExpression(members) } - static convertRegExLiteralExpression(expression: ts.Expression): Expression { - return this.createRegExLiteralExpression(expression.getText()) + convertRegExLiteralExpression(literal: ts.RegularExpressionLiteral): Expression { + return this.createRegExLiteralExpression(literal.getText()) } - static convertLiteralExpression(expression: ts.LiteralExpression): Expression { + convertLiteralExpression(expression: ts.LiteralExpression): Expression { if (ts.isNumericLiteral(expression)) { return this.convertNumericLiteralExpression(expression); } else if (ts.isBigIntLiteral(expression)) { @@ -158,7 +237,7 @@ export class AstExpressionConverter { } - static convertToken(expression: ts.Expression): Expression { + private convertToken(expression: ts.Expression): Expression { if (expression.kind == ts.SyntaxKind.TrueKeyword) { return this.createBooleanLiteralExpression(true) } else if (expression.kind == ts.SyntaxKind.FalseKeyword) { @@ -169,12 +248,12 @@ export class AstExpressionConverter { } - static convertUnknownExpression(expression: ts.Expression): Expression { + convertUnknownExpression(expression: ts.Expression): Expression { return this.createUnknownExpression(expression.getText()) } - static convertExpression(expression: ts.Expression): Expression { + convertExpression(expression: ts.Expression): Expression { if (ts.isBinaryExpression(expression)) { return this.convertBinaryExpression(expression); } else if (ts.isPrefixUnaryExpression(expression)) { @@ -193,6 +272,8 @@ export class AstExpressionConverter { return this.convertNameExpression(expression); } else if (ts.isLiteralExpression(expression)) { return this.convertLiteralExpression(expression); + } else if (ts.isObjectLiteralExpression(expression)) { + return this.convertObjectLiteralExpression(expression); } else if (ts.isToken(expression)) { return this.convertToken(expression) } else { diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index c9426f977..f1be4b9e9 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -1,7 +1,16 @@ import * as declarations from "declarations"; import { - Expression, IdentifierEntity, - LiteralExpression, NameEntity + Block, + Expression, + IdentifierEntity, + LiteralExpression, + MemberDeclaration, + ModifierDeclaration, + NameEntity, + ObjectMember, + ParameterDeclaration, + ParameterValue, ProtoMessage, + TypeParameter } from "./ast"; export class AstExpressionFactory { @@ -148,6 +157,15 @@ export class AstExpressionFactory { return this.asExpression(literalExpression); } + static createObjectLiteralDeclarationAsExpression(members: Array): Expression { + let objectLiteral = new declarations.ObjectLiteralDeclarationProto(); + objectLiteral.setMembersList(members); + + let literalExpression = new declarations.LiteralExpressionDeclarationProto(); + literalExpression.setObjectliteral(objectLiteral); + return this.asExpression(literalExpression); + } + static createRegExLiteralDeclarationAsExpression(value: string): Expression { let regExLiteralExpression = new declarations.RegExLiteralExpressionDeclarationProto(); regExLiteralExpression.setValue(value); @@ -156,4 +174,33 @@ export class AstExpressionFactory { literalExpression.setRegexliteral(regExLiteralExpression); return this.asExpression(literalExpression); } + + static createObjectProperty(name: string, initializer: Expression | null): ObjectMember { + let objectProperty = new declarations.ObjectPropertyDeclarationProto(); + objectProperty.setName(name); + if(initializer) { + objectProperty.setInitializer(initializer); + } + + let objectMember = new declarations.ObjectMemberDeclarationProto(); + objectMember.setObjectproperty(objectProperty); + return objectMember; + } + + static createObjectMethod(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, body: Block | null): ObjectMember { + let functionDeclaration = new declarations.FunctionDeclarationProto(); + functionDeclaration.setName(name); + functionDeclaration.setParametersList(parameters); + functionDeclaration.setType(type); + functionDeclaration.setTypeparametersList(typeParams); + functionDeclaration.setModifiersList(modifiers); + if (body) { + functionDeclaration.setBody(body); + } + functionDeclaration.setUid("__NO_UID__"); + + let objectMember = new declarations.ObjectMemberDeclarationProto(); + objectMember.setFunctiondeclaration(functionDeclaration); + return objectMember; + } } \ No newline at end of file diff --git a/typescript/ts-converter/src/ast/ast.ts b/typescript/ts-converter/src/ast/ast.ts index 12dea2a3a..01b65c55a 100644 --- a/typescript/ts-converter/src/ast/ast.ts +++ b/typescript/ts-converter/src/ast/ast.ts @@ -123,6 +123,8 @@ export declare class ExpressionStatement implements Declaration { serializeBinary(): Int8Array; } +export declare interface ObjectMember {} + export declare interface ParameterValue extends Declaration {} export declare class ParameterDeclaration extends Declaration { diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 32fef8b24..e698fd358 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -171,6 +171,18 @@ message ReferenceEntityProto { string uid = 1; } +message ObjectPropertyDeclarationProto { + string name = 1; + ExpressionDeclarationProto initializer = 2; +} + +message ObjectMemberDeclarationProto { + oneof type { + ObjectPropertyDeclarationProto objectProperty = 1; + FunctionDeclarationProto functionDeclaration = 2; + } +} + message StringLiteralExpressionDeclarationProto { string value = 1; } @@ -187,6 +199,10 @@ message BigIntLiteralExpressionDeclarationProto { string value = 1; } +message ObjectLiteralExpressionDeclarationProto { + repeated ObjectMemberDeclarationProto members = 1; +} + message RegExLiteralExpressionDeclarationProto { string value = 1; } @@ -197,7 +213,8 @@ message LiteralExpressionDeclarationProto { BooleanLiteralExpressionDeclarationProto booleanLiteral = 2; NumericLiteralExpressionDeclarationProto numericLiteral = 3; BigIntLiteralExpressionDeclarationProto bigIntLiteral = 4; - RegExLiteralExpressionDeclarationProto regExLiteral = 5; + ObjectLiteralExpressionDeclarationProto objectLiteral = 5; + RegExLiteralExpressionDeclarationProto regExLiteral = 6; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt index a7d863d78..54a4e42ae 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt @@ -1,5 +1,6 @@ package org.jetbrains.dukat.tsmodel +import org.jetbrains.dukat.tsmodel.expression.literal.obj.ObjectMemberDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration data class FunctionDeclaration( @@ -10,4 +11,4 @@ data class FunctionDeclaration( val modifiers: List, val body: BlockDeclaration?, override val uid: String -) : MemberDeclaration, TopLevelDeclaration, WithUidDeclaration, ParameterOwnerDeclaration \ No newline at end of file +) : MemberDeclaration, TopLevelDeclaration, WithUidDeclaration, ParameterOwnerDeclaration, ObjectMemberDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectLiteralExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectLiteralExpressionDeclaration.kt new file mode 100644 index 000000000..67d24fd58 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectLiteralExpressionDeclaration.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.tsmodel.expression.literal.obj + +import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration + +data class ObjectLiteralExpressionDeclaration( + val members: List +) : LiteralExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectMemberDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectMemberDeclaration.kt new file mode 100644 index 000000000..ff9f3e326 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectMemberDeclaration.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.tsmodel.expression.literal.obj + +interface ObjectMemberDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectPropertyDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectPropertyDeclaration.kt new file mode 100644 index 000000000..38d4ffe12 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectPropertyDeclaration.kt @@ -0,0 +1,8 @@ +package org.jetbrains.dukat.tsmodel.expression.literal.obj + +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +data class ObjectPropertyDeclaration( + val name: String, + val initializer: ExpressionDeclaration? +) : ObjectMemberDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index de968c823..f3c43df80 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -47,8 +47,11 @@ import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDec import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.obj.ObjectLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.RegExLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.obj.ObjectMemberDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.obj.ObjectPropertyDeclaration import org.jetbrains.dukat.tsmodel.expression.name.NameExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.QualifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration @@ -383,11 +386,29 @@ fun Declarations.NameExpressionDeclarationProto.convert() : NameExpressionDeclar } } +private fun Declarations.ObjectPropertyDeclarationProto.convert(): ObjectPropertyDeclaration { + return ObjectPropertyDeclaration( + name = name, + initializer = if (hasInitializer()) { + initializer.convert() + } else null + ) +} + +private fun Declarations.ObjectMemberDeclarationProto.convert(): ObjectMemberDeclaration { + return when { + hasFunctionDeclaration() -> functionDeclaration.convert() + hasObjectProperty() -> objectProperty.convert() + else -> throw Exception("unknown object member: $this") + } +} + fun Declarations.NumericLiteralExpressionDeclarationProto.convert() = NumericLiteralExpressionDeclaration(value) fun Declarations.BigIntLiteralExpressionDeclarationProto.convert() = BigIntLiteralExpressionDeclaration(value) fun Declarations.StringLiteralExpressionDeclarationProto.convert() = StringLiteralExpressionDeclaration(value) fun Declarations.BooleanLiteralExpressionDeclarationProto.convert() = BooleanLiteralExpressionDeclaration(value) fun Declarations.RegExLiteralExpressionDeclarationProto.convert() = RegExLiteralExpressionDeclaration(value) +fun Declarations.ObjectLiteralExpressionDeclarationProto.convert() = ObjectLiteralExpressionDeclaration(membersList.map { it.convert() }) fun Declarations.LiteralExpressionDeclarationProto.convert() : LiteralExpressionDeclaration { return when { @@ -395,6 +416,7 @@ fun Declarations.LiteralExpressionDeclarationProto.convert() : LiteralExpression hasBigIntLiteral() -> bigIntLiteral.convert() hasStringLiteral() -> stringLiteral.convert() hasBooleanLiteral() -> booleanLiteral.convert() + hasObjectLiteral() -> objectLiteral.convert() hasRegExLiteral() -> regExLiteral.convert() else -> throw Exception("unknown literalExpression: ${this}") } From b3324b97ea068120abda6a59c8bffb4197da5347 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2019 19:03:18 +0100 Subject: [PATCH 054/172] Unify object literal, and object type members --- typescript/ts-converter/src/AstConverter.ts | 7 +- .../src/ast/AstExpressionConverter.ts | 65 +++++++++---------- .../src/ast/AstExpressionFactory.ts | 39 +---------- typescript/ts-converter/src/ast/AstFactory.ts | 5 +- typescript/ts-converter/src/ast/ast.ts | 2 - .../ts-model-proto/src/Declarations.proto | 23 ++----- .../dukat/tsmodel/FunctionDeclaration.kt | 3 +- .../ObjectLiteralExpressionDeclaration.kt | 7 ++ .../obj/ObjectLiteralExpressionDeclaration.kt | 7 -- .../literal/obj/ObjectMemberDeclaration.kt | 3 - .../literal/obj/ObjectPropertyDeclaration.kt | 8 --- .../dukat/tsmodel/factory/convertProtobuf.kt | 21 +----- 12 files changed, 56 insertions(+), 134 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/ObjectLiteralExpressionDeclaration.kt delete mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectLiteralExpressionDeclaration.kt delete mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectMemberDeclaration.kt delete mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectPropertyDeclaration.kt diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index 99d2e0e94..8ff949996 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -167,6 +167,7 @@ export class AstConverter { if (name != null) { return this.astFactory.declareProperty( name, + null, this.convertType(nativePropertyDeclaration.type), [], false, @@ -337,8 +338,8 @@ export class AstConverter { return this.astFactory.createParameterDeclaration(name, type, initializer, vararg, optional); } - private createProperty(value: string, type: ParameterValue, typeParams: Array = [], optional: boolean): PropertyDeclaration { - return this.astFactory.declareProperty(value, type, typeParams, optional, []); + createProperty(value: string, initializer: Expression | null, type: ParameterValue, typeParams: Array = [], optional: boolean): PropertyDeclaration { + return this.astFactory.declareProperty(value, initializer, type, typeParams, optional, []); } @@ -509,7 +510,7 @@ export class AstConverter { let name = this.convertName(node.name); if (name !== null) { - return this.createProperty(name, this.convertType(node.type), [], !!node.questionToken); + return this.createProperty(name, null, this.convertType(node.type), [], !!node.questionToken); } return null; diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index db9926db8..4b9b272b3 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -1,16 +1,15 @@ import * as ts from "typescript-services-api"; import { - Block, - Expression, FunctionDeclaration, + Expression, + FunctionDeclaration, IdentifierEntity, - MemberDeclaration, ModifierDeclaration, + MemberDeclaration, NameEntity, - ObjectMember, - ParameterDeclaration, ParameterValue, - TypeParameter + PropertyDeclaration } from "./ast"; import {AstExpressionFactory} from "./AstExpressionFactory"; import {AstConverter} from "../AstConverter"; +import {ObjectLiteralElementLike} from "../../.tsdeclarations/typescript"; export class AstExpressionConverter { constructor( @@ -62,7 +61,7 @@ export class AstExpressionConverter { return AstExpressionFactory.createBooleanLiteralDeclarationAsExpression(value); } - createObjectLiteralExpression(members: Array): Expression { + createObjectLiteralExpression(members: Array): Expression { return AstExpressionFactory.createObjectLiteralDeclarationAsExpression(members); } @@ -74,14 +73,6 @@ export class AstExpressionConverter { return AstExpressionFactory.createUnknownExpressionDeclarationAsExpression(value); } - private createObjectProperty(name: string, initializer: Expression | null): ObjectMember { - return AstExpressionFactory.createObjectProperty(name, initializer); - } - - private createObjectMethod(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, body: Block | null): ObjectMember { - return AstExpressionFactory.createObjectMethod(name, parameters, type, typeParams, modifiers, body); - } - convertBinaryExpression(expression: ts.BinaryExpression): Expression { return this.createBinaryExpression( @@ -165,21 +156,27 @@ export class AstExpressionConverter { return this.createStringLiteralExpression(literal.getText()) } - private convertObjectProperty(name: ts.PropertyName, value: ts.Expression): ObjectMember | null { + private convertObjectProperty(name: ts.PropertyName, initializer: ts.Expression, optional: boolean): PropertyDeclaration | null { let convertedName = this.astConverter.convertName(name); if (convertedName) { - return this.createObjectProperty(convertedName, this.convertExpression(value)) + return this.astConverter.createProperty( + convertedName, + this.convertExpression(initializer), + this.astConverter.createTypeDeclaration("Unit"), + [], + optional + ) } else { return null; } } - private convertObjectMethod(method: ts.MethodDeclaration): ObjectMember | null { + private convertObjectMethod(method: ts.MethodDeclaration): FunctionDeclaration | null { let convertedName = this.astConverter.convertName(method.name); if (convertedName) { - return this.createObjectMethod( + return this.astConverter.createMethodDeclaration( convertedName, method.parameters.map((param, count) => this.astConverter.convertParameterDeclaration(param, count)), method.type ? this.astConverter.convertType(method.type) : this.astConverter.createTypeDeclaration("Unit"), @@ -193,25 +190,25 @@ export class AstExpressionConverter { } convertObjectLiteralExpression(literal: ts.ObjectLiteralExpression): Expression { - let members: Array = []; - - literal.properties.forEach(member => { - let objectMember: ObjectMember | null = null; - - if (ts.isPropertyAssignment(member)) { - objectMember = this.convertObjectProperty(member.name, member.initializer); - } else if (ts.isShorthandPropertyAssignment(member)) { - objectMember = this.convertObjectProperty(member.name, member.name); - } else if (ts.isMethodDeclaration(member)) { - objectMember = this.convertObjectMethod(member) - } else if (ts.isSpreadAssignment(member)) { + let members: Array = []; + + literal.properties.forEach(property => { + let member: MemberDeclaration | null = null; + + if (ts.isPropertyAssignment(property)) { + member = this.convertObjectProperty(property.name, property.initializer, !!property.questionToken); + } else if (ts.isShorthandPropertyAssignment(property)) { + member = this.convertObjectProperty(property.name, property.name, !!property.questionToken); + } else if (ts.isMethodDeclaration(property)) { + member = this.convertObjectMethod(property) + } else if (ts.isSpreadAssignment(property)) { //TODO support spread assignments - } else if (ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)) { + } else if (ts.isGetAccessorDeclaration(property) || ts.isSetAccessorDeclaration(property)) { //TODO support accessor declarations } - if (objectMember) { - members.push(objectMember); + if (member) { + members.push(member); } }); diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index f1be4b9e9..c9836a108 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -1,16 +1,10 @@ import * as declarations from "declarations"; import { - Block, Expression, IdentifierEntity, LiteralExpression, MemberDeclaration, - ModifierDeclaration, - NameEntity, - ObjectMember, - ParameterDeclaration, - ParameterValue, ProtoMessage, - TypeParameter + NameEntity } from "./ast"; export class AstExpressionFactory { @@ -157,7 +151,7 @@ export class AstExpressionFactory { return this.asExpression(literalExpression); } - static createObjectLiteralDeclarationAsExpression(members: Array): Expression { + static createObjectLiteralDeclarationAsExpression(members: Array): Expression { let objectLiteral = new declarations.ObjectLiteralDeclarationProto(); objectLiteral.setMembersList(members); @@ -174,33 +168,4 @@ export class AstExpressionFactory { literalExpression.setRegexliteral(regExLiteralExpression); return this.asExpression(literalExpression); } - - static createObjectProperty(name: string, initializer: Expression | null): ObjectMember { - let objectProperty = new declarations.ObjectPropertyDeclarationProto(); - objectProperty.setName(name); - if(initializer) { - objectProperty.setInitializer(initializer); - } - - let objectMember = new declarations.ObjectMemberDeclarationProto(); - objectMember.setObjectproperty(objectProperty); - return objectMember; - } - - static createObjectMethod(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, body: Block | null): ObjectMember { - let functionDeclaration = new declarations.FunctionDeclarationProto(); - functionDeclaration.setName(name); - functionDeclaration.setParametersList(parameters); - functionDeclaration.setType(type); - functionDeclaration.setTypeparametersList(typeParams); - functionDeclaration.setModifiersList(modifiers); - if (body) { - functionDeclaration.setBody(body); - } - functionDeclaration.setUid("__NO_UID__"); - - let objectMember = new declarations.ObjectMemberDeclarationProto(); - objectMember.setFunctiondeclaration(functionDeclaration); - return objectMember; - } } \ No newline at end of file diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index dc084b746..ccd1b50a8 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -445,9 +445,12 @@ export class AstFactory implements AstFactory { return paramValueDeclaration; } - declareProperty(name: string, type: ParameterValue, typeParams: Array, optional: boolean, modifiers: Array): PropertyDeclaration { + declareProperty(name: string, initializer: Expression | null, type: ParameterValue, typeParams: Array, optional: boolean, modifiers: Array): PropertyDeclaration { let propertyDeclaration = new declarations.PropertyDeclarationProto(); propertyDeclaration.setName(name); + if(initializer) { + propertyDeclaration.setInitializer(initializer); + } propertyDeclaration.setType(type); propertyDeclaration.setTypeparametersList(typeParams); propertyDeclaration.setOptional(optional); diff --git a/typescript/ts-converter/src/ast/ast.ts b/typescript/ts-converter/src/ast/ast.ts index 01b65c55a..12dea2a3a 100644 --- a/typescript/ts-converter/src/ast/ast.ts +++ b/typescript/ts-converter/src/ast/ast.ts @@ -123,8 +123,6 @@ export declare class ExpressionStatement implements Declaration { serializeBinary(): Int8Array; } -export declare interface ObjectMember {} - export declare interface ParameterValue extends Declaration {} export declare class ParameterDeclaration extends Declaration { diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index e698fd358..9296d8ead 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -141,10 +141,11 @@ message MethodSignatureDeclarationProto { message PropertyDeclarationProto { string name = 1; - ParameterValueDeclarationProto type = 2; - repeated TypeParameterDeclarationProto typeParameters = 3; - bool optional = 4; - repeated ModifierDeclarationProto modifiers = 5; + ExpressionDeclarationProto initializer = 2; + ParameterValueDeclarationProto type = 3; + repeated TypeParameterDeclarationProto typeParameters = 4; + bool optional = 5; + repeated ModifierDeclarationProto modifiers = 6; } message ModifierDeclarationProto { @@ -171,18 +172,6 @@ message ReferenceEntityProto { string uid = 1; } -message ObjectPropertyDeclarationProto { - string name = 1; - ExpressionDeclarationProto initializer = 2; -} - -message ObjectMemberDeclarationProto { - oneof type { - ObjectPropertyDeclarationProto objectProperty = 1; - FunctionDeclarationProto functionDeclaration = 2; - } -} - message StringLiteralExpressionDeclarationProto { string value = 1; } @@ -200,7 +189,7 @@ message BigIntLiteralExpressionDeclarationProto { } message ObjectLiteralExpressionDeclarationProto { - repeated ObjectMemberDeclarationProto members = 1; + repeated MemberEntityProto members = 1; } message RegExLiteralExpressionDeclarationProto { diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt index 54a4e42ae..a7d863d78 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt @@ -1,6 +1,5 @@ package org.jetbrains.dukat.tsmodel -import org.jetbrains.dukat.tsmodel.expression.literal.obj.ObjectMemberDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration data class FunctionDeclaration( @@ -11,4 +10,4 @@ data class FunctionDeclaration( val modifiers: List, val body: BlockDeclaration?, override val uid: String -) : MemberDeclaration, TopLevelDeclaration, WithUidDeclaration, ParameterOwnerDeclaration, ObjectMemberDeclaration \ No newline at end of file +) : MemberDeclaration, TopLevelDeclaration, WithUidDeclaration, ParameterOwnerDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/ObjectLiteralExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/ObjectLiteralExpressionDeclaration.kt new file mode 100644 index 000000000..72719acc4 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/ObjectLiteralExpressionDeclaration.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.tsmodel.expression.literal + +import org.jetbrains.dukat.tsmodel.MemberDeclaration + +data class ObjectLiteralExpressionDeclaration( + val members: List +) : LiteralExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectLiteralExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectLiteralExpressionDeclaration.kt deleted file mode 100644 index 67d24fd58..000000000 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectLiteralExpressionDeclaration.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.jetbrains.dukat.tsmodel.expression.literal.obj - -import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration - -data class ObjectLiteralExpressionDeclaration( - val members: List -) : LiteralExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectMemberDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectMemberDeclaration.kt deleted file mode 100644 index ff9f3e326..000000000 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectMemberDeclaration.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dukat.tsmodel.expression.literal.obj - -interface ObjectMemberDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectPropertyDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectPropertyDeclaration.kt deleted file mode 100644 index 38d4ffe12..000000000 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/obj/ObjectPropertyDeclaration.kt +++ /dev/null @@ -1,8 +0,0 @@ -package org.jetbrains.dukat.tsmodel.expression.literal.obj - -import org.jetbrains.dukat.tsmodel.ExpressionDeclaration - -data class ObjectPropertyDeclaration( - val name: String, - val initializer: ExpressionDeclaration? -) : ObjectMemberDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index f3c43df80..30cee074e 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -47,11 +47,9 @@ import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDec import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDeclaration -import org.jetbrains.dukat.tsmodel.expression.literal.obj.ObjectLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.ObjectLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.RegExLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration -import org.jetbrains.dukat.tsmodel.expression.literal.obj.ObjectMemberDeclaration -import org.jetbrains.dukat.tsmodel.expression.literal.obj.ObjectPropertyDeclaration import org.jetbrains.dukat.tsmodel.expression.name.NameExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.QualifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration @@ -386,23 +384,6 @@ fun Declarations.NameExpressionDeclarationProto.convert() : NameExpressionDeclar } } -private fun Declarations.ObjectPropertyDeclarationProto.convert(): ObjectPropertyDeclaration { - return ObjectPropertyDeclaration( - name = name, - initializer = if (hasInitializer()) { - initializer.convert() - } else null - ) -} - -private fun Declarations.ObjectMemberDeclarationProto.convert(): ObjectMemberDeclaration { - return when { - hasFunctionDeclaration() -> functionDeclaration.convert() - hasObjectProperty() -> objectProperty.convert() - else -> throw Exception("unknown object member: $this") - } -} - fun Declarations.NumericLiteralExpressionDeclarationProto.convert() = NumericLiteralExpressionDeclaration(value) fun Declarations.BigIntLiteralExpressionDeclarationProto.convert() = BigIntLiteralExpressionDeclaration(value) fun Declarations.StringLiteralExpressionDeclarationProto.convert() = StringLiteralExpressionDeclaration(value) From a74051cf7cbd495b4c41ea8a0fda8421b5b29b93 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2019 19:20:09 +0100 Subject: [PATCH 055/172] Add initializer to PropertyDeclaration --- .../src/org/jetbrains/dukat/tsmodel/PropertyDeclaration.kt | 2 +- .../src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/PropertyDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/PropertyDeclaration.kt index 94da649db..9324877a1 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/PropertyDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/PropertyDeclaration.kt @@ -1,10 +1,10 @@ package org.jetbrains.dukat.tsmodel -import org.jetbrains.dukat.astCommon.MemberEntity import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration data class PropertyDeclaration( val name: String, + val initializer: ExpressionDeclaration? = null, val type: ParameterValueDeclaration, val typeParameters: List, val optional: Boolean, diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 30cee074e..aa72fd0c6 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -225,6 +225,9 @@ fun Declarations.TopLevelEntityProto.convert(): TopLevelDeclaration { fun Declarations.PropertyDeclarationProto.convert(): PropertyDeclaration { return PropertyDeclaration( name, + if (hasInitializer()) { + initializer.convert() + } else null, type.convert(), typeParametersList.map { it.convert() }, optional, From aba41d0c0ea5006a9dcea30995411114afd31ea7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2019 20:14:27 +0100 Subject: [PATCH 056/172] Gather object types --- .../data/javascript/object/construct.d.kt | 35 +++++++++++++++++ .../data/javascript/object/construct.d.ts | 24 ++++++++++++ .../test/data/javascript/object/object.d.kt | 23 +++++++++++ .../test/data/javascript/object/object.d.ts | 10 +++++ .../dukat/js/type/analysis/expression.kt | 10 ++++- .../dukat/js/type/analysis/introduceTypes.kt | 7 ++++ .../resolution/constraintToDeclaration.kt | 38 +++++++++++++++---- 7 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 compiler/test/data/javascript/object/construct.d.kt create mode 100644 compiler/test/data/javascript/object/construct.d.ts create mode 100644 compiler/test/data/javascript/object/object.d.kt create mode 100644 compiler/test/data/javascript/object/object.d.ts diff --git a/compiler/test/data/javascript/object/construct.d.kt b/compiler/test/data/javascript/object/construct.d.kt new file mode 100644 index 000000000..c9401796f --- /dev/null +++ b/compiler/test/data/javascript/object/construct.d.kt @@ -0,0 +1,35 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface `T$0` { + companion object { + var x: Number + var y: Number + var z: Number + } +} + +external object v { + var x: Number + var y: Number + var z: Number + fun negate(x: Any?, y: Any?, z: Any?): `T$0` + var double: `T$0` +} + +external fun negate(x: Any?, y: Any?, z: Any?): `T$0` \ No newline at end of file diff --git a/compiler/test/data/javascript/object/construct.d.ts b/compiler/test/data/javascript/object/construct.d.ts new file mode 100644 index 000000000..8f6b00a43 --- /dev/null +++ b/compiler/test/data/javascript/object/construct.d.ts @@ -0,0 +1,24 @@ + +var v = {}; + +v.x = 5; +v.y = 5; +v.z = 5; + + +function negate(x, y, z) { + return { + x: -x, + y: -y, + z: -z + } +} + +v.negate = negate; + + +v.double = {} + +v.double.x = 2*v.x; +v.double.y = 2*v.y; +v.double.z = 2*v.z; \ No newline at end of file diff --git a/compiler/test/data/javascript/object/object.d.kt b/compiler/test/data/javascript/object/object.d.kt new file mode 100644 index 000000000..14999e3c9 --- /dev/null +++ b/compiler/test/data/javascript/object/object.d.kt @@ -0,0 +1,23 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external object v { + var x: Number + var y: Number + var z: Number + fun foo(): Number +} \ No newline at end of file diff --git a/compiler/test/data/javascript/object/object.d.ts b/compiler/test/data/javascript/object/object.d.ts new file mode 100644 index 000000000..8fd5befb4 --- /dev/null +++ b/compiler/test/data/javascript/object/object.d.ts @@ -0,0 +1,10 @@ + +var v = { + x: 5, + y: 5, + z: 5, + + foo() { + return 5; + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 20b78fc8f..401f643ec 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -11,7 +11,7 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConst import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.call.CallArgumentConstraint import org.jetbrains.dukat.js.type.constraint.immutable.call.CallResultConstraint -import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint +import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration @@ -23,6 +23,7 @@ import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDec import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.NumericLiteralExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.ObjectLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration @@ -106,12 +107,19 @@ fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Const ) } +fun ObjectLiteralExpressionDeclaration.calculateConstraints() : ObjectConstraint { + val obj = ObjectConstraint() + members.forEach { it.addTo(obj) } + return obj +} + fun LiteralExpressionDeclaration.calculateConstraints() : Constraint { return when (this) { is StringLiteralExpressionDeclaration -> StringTypeConstraint is NumericLiteralExpressionDeclaration -> NumberTypeConstraint is BigIntLiteralExpressionDeclaration -> BigIntTypeConstraint is BooleanLiteralExpressionDeclaration -> BooleanTypeConstraint + is ObjectLiteralExpressionDeclaration -> this.calculateConstraints() else -> raiseConcern("Unexpected literal expression type <${this::class}>") { CompositeConstraint(NoTypeConstraint) } } } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index 744d4df14..9d237259a 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -21,6 +21,7 @@ import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.InterfaceDeclaration import org.jetbrains.dukat.tsmodel.MemberDeclaration import org.jetbrains.dukat.tsmodel.ModifierDeclaration +import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration @@ -54,9 +55,14 @@ fun ConstructorDeclaration.addTo(owner: PropertyOwner) { fun InterfaceDeclaration.addTo(owner: PropertyOwner) */ +fun PropertyDeclaration.addTo(owner: PropertyOwner) { + owner[name] = initializer?.calculateConstraints(owner) ?: VoidTypeConstraint +} + fun MemberDeclaration.addTo(owner: PropertyOwner) { when (this) { is FunctionDeclaration -> this.addTo(owner) + is PropertyDeclaration -> this.addTo(owner) else -> raiseConcern("Unexpected member entity type <${this::class}>") { this } } } @@ -64,6 +70,7 @@ fun MemberDeclaration.addTo(owner: PropertyOwner) { fun MemberDeclaration.addToClass(owner: ClassConstraint) { when (this) { is FunctionDeclaration -> if (this.modifiers.contains(ModifierDeclaration.STATIC_KEYWORD)) { this.addTo(owner) } else { this.addTo(owner.prototype) } + is PropertyDeclaration -> this.addTo(owner) else -> raiseConcern("Unexpected member entity type <${this::class}>") { this } } } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index 3321f479e..68d035476 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -10,6 +10,7 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConst import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint +import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint import org.jetbrains.dukat.js.type.type.anyNullableType import org.jetbrains.dukat.js.type.type.booleanType import org.jetbrains.dukat.js.type.type.numberType @@ -21,8 +22,10 @@ import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.MemberDeclaration import org.jetbrains.dukat.tsmodel.ModifierDeclaration import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration +import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration import org.jetbrains.dukat.tsmodel.types.TypeDeclaration @@ -30,11 +33,20 @@ val EXPORT_MODIFIERS = listOf(ModifierDeclaration.EXPORT_KEYWORD) val STATIC_MODIFIERS = listOf(ModifierDeclaration.STATIC_KEYWORD) fun getVariableDeclaration(name: String, type: ParameterValueDeclaration) = VariableDeclaration( - name = name, - type = type, - modifiers = EXPORT_MODIFIERS, - initializer = null, - uid = getUID() + name = name, + type = type, + modifiers = EXPORT_MODIFIERS, + initializer = null, + uid = getUID() +) + +fun getPropertyDeclaration(name: String, type: ParameterValueDeclaration, isStatic: Boolean) = PropertyDeclaration( + name = name, + initializer = null, + type = type, + typeParameters = emptyList(), + optional = false, + modifiers = if (isStatic) emptyList() else STATIC_MODIFIERS ) fun Constraint.toParameterDeclaration(name: String) = ParameterDeclaration( @@ -63,10 +75,10 @@ fun FunctionConstraint.toMemberDeclaration(name: String, isStatic: Boolean) : Me return this.toDeclaration(name).withStaticModifier(isStatic) } -fun Constraint.toMemberDeclaration(name: String, isStatic: Boolean) : MemberDeclaration? { +fun Constraint.toMemberDeclaration(name: String, isStatic: Boolean = false) : MemberDeclaration? { return when (this) { is FunctionConstraint -> this.toMemberDeclaration(name, isStatic) - else -> raiseConcern("Cannot treat constraint of type <${this::class}> as member.") { null } + else -> this.toType()?.let { type -> getPropertyDeclaration(name, type, isStatic) } } } @@ -95,13 +107,23 @@ fun ClassConstraint.toDeclaration(name: String) : ClassDeclaration { ) } -fun Constraint.toType() : TypeDeclaration? { +fun ObjectConstraint.toType() : ObjectLiteralDeclaration? { + return ObjectLiteralDeclaration( + members = propertyNames.mapNotNull { memberName -> + this[memberName]?.toMemberDeclaration(name = memberName) + }, + nullable = true + ) +} + +fun Constraint.toType() : ParameterValueDeclaration? { return when (this) { is NumberTypeConstraint -> numberType is BigIntTypeConstraint -> numberType is BooleanTypeConstraint -> booleanType is StringTypeConstraint -> stringType is VoidTypeConstraint -> voidType + is ObjectConstraint -> this.toType() else -> anyNullableType } } From 035b90850afb2fc8751a4226f48121ff0f507960 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2019 20:37:46 +0100 Subject: [PATCH 057/172] Make operators more aggressive --- .../src/org/jetbrains/dukat/js/type/analysis/expression.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 401f643ec..4400a9a3b 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -70,9 +70,11 @@ fun UnaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Cons return when (operator) { "--", "++", "~" -> { operandConstraints += NumberTypeConstraint + owner[operand] = NumberTypeConstraint NumberTypeConstraint } "-", "+" -> { + operandConstraints += NumberTypeConstraint NumberTypeConstraint } "!" -> { From d6a1a644b8afeec6ea70b1930e041341cf173a86 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Nov 2019 12:18:25 +0100 Subject: [PATCH 058/172] Add infrastructure to process variations in a branching code block --- .../dukat/js/type/analysis/PathDescriptor.kt | 37 ++++++++ .../dukat/js/type/analysis/expression.kt | 47 +++++----- .../dukat/js/type/analysis/introduceTypes.kt | 94 +++++++++++-------- 3 files changed, 115 insertions(+), 63 deletions(-) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt new file mode 100644 index 000000000..573472acb --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt @@ -0,0 +1,37 @@ +package org.jetbrains.dukat.js.type.analysis + +class PathWalker { + private val directions = mutableListOf() + private var position = 0 + + tailrec fun startNextPath() : Boolean { + position = 0 + + return if (directions.lastIndex >= 0) { + val lastDirection = directions[directions.lastIndex] + + if (lastDirection == Direction.First) { + directions[directions.lastIndex] = Direction.Second + true + } else { + directions.removeAt(directions.lastIndex) + startNextPath() + } + } else { + false + } + } + + fun getNextDirection() : Direction { + if (directions.size <= position) { + directions.add(Direction.First) + } + + return directions[position++] + } + + enum class Direction { + First, + Second + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 4400a9a3b..7f02e6c8e 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -27,9 +27,9 @@ import org.jetbrains.dukat.tsmodel.expression.literal.ObjectLiteralExpressionDec import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration -fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { - val rightConstraints = right.calculateConstraints(owner) - val leftConstraints = left.calculateConstraints(owner) +fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { + val rightConstraints = right.calculateConstraints(owner, path) + val leftConstraints = left.calculateConstraints(owner, path) return when (operator) { // Assignments @@ -44,8 +44,11 @@ fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Con // Non-assignments "&&", "||" -> { - //TODO make this branching - leftConstraints + //TODO only calculate the constraints of the chosen path with this operator + when (path.getNextDirection()) { + PathWalker.Direction.First -> leftConstraints + PathWalker.Direction.Second -> rightConstraints + } } "-", "*", "/", "**", "%", "++", "--" -> { rightConstraints += NumberTypeConstraint @@ -64,8 +67,8 @@ fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Con } } -fun UnaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { - val operandConstraints = operand.calculateConstraints(owner) +fun UnaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { + val operandConstraints = operand.calculateConstraints(owner, path) return when (operator) { "--", "++", "~" -> { @@ -86,14 +89,14 @@ fun UnaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Cons } } -fun TypeOfExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { - expression.calculateConstraints(owner) +fun TypeOfExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { + expression.calculateConstraints(owner, path) return StringTypeConstraint } -fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { - val callTargetConstraints = expression.calculateConstraints(owner) - val argumentConstraints = arguments.map { it.calculateConstraints(owner) } +fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { + val callTargetConstraints = expression.calculateConstraints(owner, path) + val argumentConstraints = arguments.map { it.calculateConstraints(owner, path) } argumentConstraints.forEachIndexed { argumentNumber, arg -> arg += CallArgumentConstraint( @@ -109,32 +112,32 @@ fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Const ) } -fun ObjectLiteralExpressionDeclaration.calculateConstraints() : ObjectConstraint { +fun ObjectLiteralExpressionDeclaration.calculateConstraints(path: PathWalker) : ObjectConstraint { val obj = ObjectConstraint() - members.forEach { it.addTo(obj) } + members.forEach { it.addTo(obj, path) } return obj } -fun LiteralExpressionDeclaration.calculateConstraints() : Constraint { +fun LiteralExpressionDeclaration.calculateConstraints(path: PathWalker) : Constraint { return when (this) { is StringLiteralExpressionDeclaration -> StringTypeConstraint is NumericLiteralExpressionDeclaration -> NumberTypeConstraint is BigIntLiteralExpressionDeclaration -> BigIntTypeConstraint is BooleanLiteralExpressionDeclaration -> BooleanTypeConstraint - is ObjectLiteralExpressionDeclaration -> this.calculateConstraints() + is ObjectLiteralExpressionDeclaration -> this.calculateConstraints(path) else -> raiseConcern("Unexpected literal expression type <${this::class}>") { CompositeConstraint(NoTypeConstraint) } } } -fun ExpressionDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { +fun ExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { return when (this) { is IdentifierExpressionDeclaration -> owner[this] ?: ReferenceConstraint(this.identifier) is PropertyAccessExpressionDeclaration -> owner[this] ?: CompositeConstraint() //TODO replace this with a reference constraint (of some sort) - is BinaryExpressionDeclaration -> this.calculateConstraints(owner) - is UnaryExpressionDeclaration -> this.calculateConstraints(owner) - is TypeOfExpressionDeclaration -> this.calculateConstraints(owner) - is CallExpressionDeclaration -> this.calculateConstraints(owner) - is LiteralExpressionDeclaration -> this.calculateConstraints() + is BinaryExpressionDeclaration -> this.calculateConstraints(owner, path) + is UnaryExpressionDeclaration -> this.calculateConstraints(owner, path) + is TypeOfExpressionDeclaration -> this.calculateConstraints(owner, path) + is CallExpressionDeclaration -> this.calculateConstraints(owner, path) + is LiteralExpressionDeclaration -> this.calculateConstraints(path) else -> CompositeConstraint(NoTypeConstraint) } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index 9d237259a..f40e6315f 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -28,22 +28,32 @@ import org.jetbrains.dukat.tsmodel.VariableDeclaration fun FunctionDeclaration.addTo(owner: PropertyOwner) { if (this.body != null) { - val functionScope = Scope() - - val parameterConstraints = MutableList(parameters.size) { i -> - // Store constraints of parameters in scope, - // and in parameter list (in case the variable is replaced) - val parameterConstraint = CompositeConstraint() - functionScope[parameters[i].name] = parameterConstraint - parameters[i].name to parameterConstraint - } + val pathWalker = PathWalker() + + val versions = mutableListOf() + + do { + val functionScope = Scope() + + val parameterConstraints = MutableList(parameters.size) { i -> + // Store constraints of parameters in scope, + // and in parameter list (in case the variable is replaced) + val parameterConstraint = CompositeConstraint() + functionScope[parameters[i].name] = parameterConstraint + parameters[i].name to parameterConstraint + } + + val returnTypeConstraints = body!!.calculateConstraints(functionScope, pathWalker) + + versions.add(FunctionConstraint( + returnConstraints = returnTypeConstraints, + parameterConstraints = parameterConstraints + )) + } while (pathWalker.startNextPath()) - val returnTypeConstraints = body!!.calculateConstraints(functionScope) + //TODO unify versions of function - owner[name] = FunctionConstraint( - returnConstraints = returnTypeConstraints, - parameterConstraints = parameterConstraints - ) + owner[name] = versions[0] } } @@ -55,32 +65,32 @@ fun ConstructorDeclaration.addTo(owner: PropertyOwner) { fun InterfaceDeclaration.addTo(owner: PropertyOwner) */ -fun PropertyDeclaration.addTo(owner: PropertyOwner) { - owner[name] = initializer?.calculateConstraints(owner) ?: VoidTypeConstraint +fun PropertyDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { + owner[name] = initializer?.calculateConstraints(owner, path) ?: VoidTypeConstraint } -fun MemberDeclaration.addTo(owner: PropertyOwner) { +fun MemberDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { when (this) { is FunctionDeclaration -> this.addTo(owner) - is PropertyDeclaration -> this.addTo(owner) + is PropertyDeclaration -> this.addTo(owner, path) else -> raiseConcern("Unexpected member entity type <${this::class}>") { this } } } -fun MemberDeclaration.addToClass(owner: ClassConstraint) { +fun MemberDeclaration.addToClass(owner: ClassConstraint, path: PathWalker) { when (this) { is FunctionDeclaration -> if (this.modifiers.contains(ModifierDeclaration.STATIC_KEYWORD)) { this.addTo(owner) } else { this.addTo(owner.prototype) } - is PropertyDeclaration -> this.addTo(owner) + is PropertyDeclaration -> this.addTo(owner, path) else -> raiseConcern("Unexpected member entity type <${this::class}>") { this } } } -fun ClassDeclaration.addTo(owner: PropertyOwner) { +fun ClassDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { val className = name // Needed for smart cast if(className is IdentifierEntity) { val classConstraint = ClassConstraint() - members.forEach { it.addToClass(classConstraint) } + members.forEach { it.addToClass(classConstraint, path) } owner[className.value] = classConstraint } else { @@ -88,45 +98,45 @@ fun ClassDeclaration.addTo(owner: PropertyOwner) { } } -fun BlockDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { - return statements.calculateConstraints(owner) +fun BlockDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { + return statements.calculateConstraints(owner, path) } -fun VariableDeclaration.addTo(owner: PropertyOwner) { - owner[name] = initializer?.calculateConstraints(owner) ?: VoidTypeConstraint +fun VariableDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { + owner[name] = initializer?.calculateConstraints(owner, path) ?: VoidTypeConstraint } -fun ExpressionStatementDeclaration.calculateConstraints(owner: PropertyOwner) { - expression.calculateConstraints(owner) +fun ExpressionStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) { + expression.calculateConstraints(owner, path) } -fun ReturnStatementDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint { - return expression?.calculateConstraints(owner) ?: VoidTypeConstraint +fun ReturnStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { + return expression?.calculateConstraints(owner, path) ?: VoidTypeConstraint } -fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner) : Constraint? { +fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { var returnTypeConstraints: Constraint? = null when (this) { is FunctionDeclaration -> this.addTo(owner) - is ClassDeclaration -> this.addTo(owner) - is VariableDeclaration -> this.addTo(owner) - is ExpressionStatementDeclaration -> this.calculateConstraints(owner) - is BlockDeclaration -> returnTypeConstraints = this.calculateConstraints(owner) - is ReturnStatementDeclaration -> returnTypeConstraints = this.calculateConstraints(owner) + is ClassDeclaration -> this.addTo(owner, path) + is VariableDeclaration -> this.addTo(owner, path) + is ExpressionStatementDeclaration -> this.calculateConstraints(owner, path) + is BlockDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) + is ReturnStatementDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) is InterfaceDeclaration, - is ModuleDeclaration -> { } + is ModuleDeclaration -> { /* These statements aren't supported in JS (ignore them) */ } else -> raiseConcern("Unexpected top level entity type <${this::class}>") { } } return returnTypeConstraints } -fun List.calculateConstraints(owner: PropertyOwner) : Constraint { +fun List.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { var returnTypeConstraints: Constraint = VoidTypeConstraint for(statement in this) { - val statementReturnTypeConstraints = statement.calculateConstraints(owner) + val statementReturnTypeConstraints = statement.calculateConstraints(owner, path) if(statementReturnTypeConstraints != null) { // This should only happen once per code block @@ -137,11 +147,13 @@ fun List.calculateConstraints(owner: PropertyOwner) : Const return returnTypeConstraints } -fun ModuleDeclaration.calculateConstraints(owner: PropertyOwner) = declarations.calculateConstraints(owner) +fun ModuleDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) = declarations.calculateConstraints(owner, path) fun ModuleDeclaration.introduceTypes(exportResolver: ExportResolver) : ModuleDeclaration { val scope = Scope() - calculateConstraints(scope) + val pathWalker = PathWalker() + calculateConstraints(scope, pathWalker) + //TODO check other paths val declarations = exportResolver.resolve(scope) return copy(declarations = declarations) } From 4178e59ad3630804f87057cb4b6a3477e70cec72 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Nov 2019 13:46:09 +0100 Subject: [PATCH 059/172] Add if-statement --- typescript/ts-converter/src/AstConverter.ts | 6 ++++++ typescript/ts-converter/src/ast/AstFactory.ts | 17 ++++++++++++++++- typescript/ts-converter/src/ast/ast.ts | 14 +++++++++++++- .../ts-model-proto/src/Declarations.proto | 7 +++++++ .../dukat/tsmodel/IfStatementDeclaration.kt | 7 +++++++ .../tsmodel/ReturnStatementDeclaration.kt | 2 +- .../dukat/tsmodel/factory/convertProtobuf.kt | 18 ++++++++++++++++++ 7 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/IfStatementDeclaration.kt diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index 8ff949996..a2468eff3 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -822,6 +822,12 @@ export class AstConverter { res.push(this.astFactory.createExpressionStatement( this.astExpressionConverter.convertExpression(statement.expression) )); + } else if (ts.isIfStatement(statement)) { + res.push(this.astFactory.createIfStatement( + this.astExpressionConverter.convertExpression(statement.expression), + this.convertTopLevelStatement(statement.thenStatement), + this.convertTopLevelStatement(statement.elseStatement) + )) } else if (ts.isReturnStatement(statement)) { let expression : Expression | null = null; if (statement.expression) { diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index ccd1b50a8..c00d9d9ee 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -16,6 +16,7 @@ import { FunctionTypeDeclaration, HeritageClauseDeclaration, IdentifierEntity, + IfStatement, ImportEqualsDeclaration, IndexSignatureDeclaration, InterfaceDeclaration, @@ -33,6 +34,7 @@ import { ProtoMessage, QualifierEntity, ReferenceEntity, + ReturnStatement, SourceFileDeclaration, SourceSet, StringLiteralDeclaration, @@ -129,7 +131,20 @@ export class AstFactory implements AstFactory { return topLevelEntity; } - createReturnStatement(expression: Expression | null): ExpressionStatement { + createIfStatement(condition: Expression, thenStatement: Array, elseStatement: Array | null): IfStatement { + let ifStatement = new declarations.IfStatementDeclarationProto(); + ifStatement.setCondition(condition); + ifStatement.setThenstatementList(thenStatement); + if (elseStatement) { + ifStatement.setElsestatementList(elseStatement); + } + + let topLevelEntity = new declarations.TopLevelEntityProto(); + topLevelEntity.setIfstatement(ifStatement); + return topLevelEntity; + } + + createReturnStatement(expression: Expression | null): ReturnStatement { let returnStatement = new declarations.ReturnStatementDeclarationProto(); if (expression) { returnStatement.setExpression(expression); diff --git a/typescript/ts-converter/src/ast/ast.ts b/typescript/ts-converter/src/ast/ast.ts index 12dea2a3a..68d9eaed7 100644 --- a/typescript/ts-converter/src/ast/ast.ts +++ b/typescript/ts-converter/src/ast/ast.ts @@ -123,6 +123,18 @@ export declare class ExpressionStatement implements Declaration { serializeBinary(): Int8Array; } +export declare class IfStatement implements Declaration { + condition: Expression; + thenStatement: Declaration; + elseStatement?: Declaration; + serializeBinary(): Int8Array; +} + +export declare class ReturnStatement implements Declaration { + expression: Expression; + serializeBinary(): Int8Array; +} + export declare interface ParameterValue extends Declaration {} export declare class ParameterDeclaration extends Declaration { @@ -158,7 +170,7 @@ export declare class TypeDeclaration implements ParameterValue { } export declare class Block implements Declaration { - statements: Array + statements: Array; serializeBinary(): Int8Array; } diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 9296d8ead..60ef776f0 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -264,6 +264,12 @@ message ExpressionStatementDeclarationProto { ExpressionDeclarationProto expression = 1; } +message IfStatementDeclarationProto { + ExpressionDeclarationProto condition = 1; + repeated TopLevelEntityProto thenStatement = 2; + repeated TopLevelEntityProto elseStatement = 3; +} + message ReturnStatementDeclarationProto { ExpressionDeclarationProto expression = 1; } @@ -336,6 +342,7 @@ message TopLevelEntityProto { ImportEqualsDeclarationProto importEquals = 9; ExpressionStatementDeclarationProto expressionStatement = 10; ReturnStatementDeclarationProto returnStatement = 11; + IfStatementDeclarationProto ifStatement = 12; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/IfStatementDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/IfStatementDeclaration.kt new file mode 100644 index 000000000..fe944d430 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/IfStatementDeclaration.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.tsmodel + +data class IfStatementDeclaration( + val condition: ExpressionDeclaration, + val thenStatement: TopLevelDeclaration, + val elseStatement: TopLevelDeclaration? +) : TopLevelDeclaration diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ReturnStatementDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ReturnStatementDeclaration.kt index ad7e2a888..f1ec82406 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ReturnStatementDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ReturnStatementDeclaration.kt @@ -1,5 +1,5 @@ package org.jetbrains.dukat.tsmodel -class ReturnStatementDeclaration( +data class ReturnStatementDeclaration( val expression: ExpressionDeclaration? ) : TopLevelDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index aa72fd0c6..111acdff5 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -18,6 +18,7 @@ import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.HeritageClauseDeclaration +import org.jetbrains.dukat.tsmodel.IfStatementDeclaration import org.jetbrains.dukat.tsmodel.ImportEqualsDeclaration import org.jetbrains.dukat.tsmodel.InterfaceDeclaration import org.jetbrains.dukat.tsmodel.MemberDeclaration @@ -193,6 +194,22 @@ fun Declarations.ImportEqualsDeclarationProto.convert(): ImportEqualsDeclaration return ImportEqualsDeclaration(name, moduleReference.convert(), uid) } +fun List.convert(): TopLevelDeclaration? { + return when { + this.isEmpty() -> null + this.size == 1 -> this[0].convert() + else -> BlockDeclaration( this.map { it.convert() } ) + } +} + +fun Declarations.IfStatementDeclarationProto.convert(): IfStatementDeclaration { + return IfStatementDeclaration( + condition = condition.convert(), + thenStatement = thenStatementList.convert() ?: BlockDeclaration(emptyList()), + elseStatement = elseStatementList.convert() + ) +} + fun Declarations.ExpressionStatementDeclarationProto.convert(): ExpressionStatementDeclaration { return ExpressionStatementDeclaration(expression.convert()) } @@ -216,6 +233,7 @@ fun Declarations.TopLevelEntityProto.convert(): TopLevelDeclaration { hasModuleDeclaration() -> moduleDeclaration.convert() hasExportAssignment() -> exportAssignment.convert() hasImportEquals() -> importEquals.convert() + hasIfStatement() -> ifStatement.convert() hasExpressionStatement() -> expressionStatement.convert() hasReturnStatement() -> returnStatement.convert() else -> throw Exception("unknown TopLevelEntity: ${this}") From 50481cd156021dbed1a042559f149cc2d9da2c9b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Nov 2019 14:25:46 +0100 Subject: [PATCH 060/172] Support if-statements (only taking first path for now) --- .../test/data/javascript/conditional/if.d.kt | 20 ++++++++++++++ .../test/data/javascript/conditional/if.d.ts | 16 +++++++++++ .../dukat/js/type/analysis/introduceTypes.kt | 27 ++++++++++++------- 3 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 compiler/test/data/javascript/conditional/if.d.kt create mode 100644 compiler/test/data/javascript/conditional/if.d.ts diff --git a/compiler/test/data/javascript/conditional/if.d.kt b/compiler/test/data/javascript/conditional/if.d.kt new file mode 100644 index 000000000..b8a0d929d --- /dev/null +++ b/compiler/test/data/javascript/conditional/if.d.kt @@ -0,0 +1,20 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun max(a: Any?, b: Any?): Any? + +external fun negate(a: Number): Number \ No newline at end of file diff --git a/compiler/test/data/javascript/conditional/if.d.ts b/compiler/test/data/javascript/conditional/if.d.ts new file mode 100644 index 000000000..63524874c --- /dev/null +++ b/compiler/test/data/javascript/conditional/if.d.ts @@ -0,0 +1,16 @@ + +function max(a, b) { + if (a > b) + return a + else + return b +} + +function negate(a) { + if(isNum(a)) + return -a + else if(isBool(a)) + return !a + else + return null +} diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index f40e6315f..eb3b6e933 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -4,6 +4,7 @@ import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner @@ -18,6 +19,7 @@ import org.jetbrains.dukat.tsmodel.SourceFileDeclaration import org.jetbrains.dukat.tsmodel.SourceSetDeclaration import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.IfStatementDeclaration import org.jetbrains.dukat.tsmodel.InterfaceDeclaration import org.jetbrains.dukat.tsmodel.MemberDeclaration import org.jetbrains.dukat.tsmodel.ModifierDeclaration @@ -43,7 +45,7 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) { parameters[i].name to parameterConstraint } - val returnTypeConstraints = body!!.calculateConstraints(functionScope, pathWalker) + val returnTypeConstraints = body!!.calculateConstraints(functionScope, pathWalker) ?: VoidTypeConstraint versions.add(FunctionConstraint( returnConstraints = returnTypeConstraints, @@ -98,7 +100,7 @@ fun ClassDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { } } -fun BlockDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { +fun BlockDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { return statements.calculateConstraints(owner, path) } @@ -106,6 +108,15 @@ fun VariableDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { owner[name] = initializer?.calculateConstraints(owner, path) ?: VoidTypeConstraint } +fun IfStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { + condition.calculateConstraints(owner, path) += BooleanTypeConstraint + + return when (path.getNextDirection()) { + PathWalker.Direction.First -> thenStatement.calculateConstraints(owner, path) + PathWalker.Direction.Second -> elseStatement?.calculateConstraints(owner, path) + } +} + fun ExpressionStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) { expression.calculateConstraints(owner, path) } @@ -121,6 +132,7 @@ fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWal is FunctionDeclaration -> this.addTo(owner) is ClassDeclaration -> this.addTo(owner, path) is VariableDeclaration -> this.addTo(owner, path) + is IfStatementDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) is ExpressionStatementDeclaration -> this.calculateConstraints(owner, path) is BlockDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) is ReturnStatementDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) @@ -132,19 +144,16 @@ fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWal return returnTypeConstraints } -fun List.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { - var returnTypeConstraints: Constraint = VoidTypeConstraint - - for(statement in this) { +fun List.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { + this.forEach { statement -> val statementReturnTypeConstraints = statement.calculateConstraints(owner, path) if(statementReturnTypeConstraints != null) { - // This should only happen once per code block - returnTypeConstraints = statementReturnTypeConstraints + return statementReturnTypeConstraints } } - return returnTypeConstraints + return null } fun ModuleDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) = declarations.calculateConstraints(owner, path) From 372a4f2a7b674306a2382a5696597ab5de0e02b6 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 11:00:42 +0100 Subject: [PATCH 061/172] Track modification of function results --- .../dukat/js/type/analysis/expression.kt | 10 ++-- .../composite/ReferenceConstraint.kt | 55 ------------------- .../immutable/call/CallResultConstraint.kt | 17 ------ .../PropertyOwnerReferenceConstraint.kt | 37 +++++++++++++ .../reference/ReferenceConstraint.kt | 36 ++++++++++++ .../call/CallArgumentConstraint.kt | 9 ++- .../reference/call/CallResultConstraint.kt | 15 +++++ .../call/getResolvedFunction.kt | 3 +- .../dukat/js/type/property_owner/Scope.kt | 2 +- 9 files changed, 98 insertions(+), 86 deletions(-) delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/ReferenceConstraint.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallResultConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/{immutable => reference}/call/CallArgumentConstraint.kt (77%) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/{immutable => reference}/call/getResolvedFunction.kt (76%) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 7f02e6c8e..b7256d0aa 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -1,7 +1,7 @@ package org.jetbrains.dukat.js.type.analysis import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.composite.ReferenceConstraint +import org.jetbrains.dukat.js.type.constraint.reference.ReferenceConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConstraint @@ -9,8 +9,8 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeCons import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint -import org.jetbrains.dukat.js.type.constraint.immutable.call.CallArgumentConstraint -import org.jetbrains.dukat.js.type.constraint.immutable.call.CallResultConstraint +import org.jetbrains.dukat.js.type.constraint.reference.call.CallArgumentConstraint +import org.jetbrains.dukat.js.type.constraint.reference.call.CallResultConstraint import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration @@ -101,14 +101,12 @@ fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: P argumentConstraints.forEachIndexed { argumentNumber, arg -> arg += CallArgumentConstraint( callTargetConstraints, - argumentConstraints, argumentNumber ) } return CallResultConstraint( - callTargetConstraints, - argumentConstraints + callTargetConstraints ) } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/ReferenceConstraint.kt deleted file mode 100644 index e8029107c..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/ReferenceConstraint.kt +++ /dev/null @@ -1,55 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.composite - -import org.jetbrains.dukat.astCommon.IdentifierEntity -import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -import org.jetbrains.dukat.panic.raiseConcern - -data class ReferenceConstraint( - val identifier: IdentifierEntity, - val parent: ReferenceConstraint? = null -) : PropertyOwnerConstraint { - override val propertyNames: Set - get() = raiseConcern("Properties of a reference should never be listed.") { emptySet() } - - private val modifiedProperties = LinkedHashMap() - - override fun set(name: String, data: Constraint) { - modifiedProperties[name] = data - } - - override fun get(name: String): Constraint { - return modifiedProperties[name] ?: ReferenceConstraint(IdentifierEntity(name), this) - } - - override fun resolve(owner: PropertyOwner): Constraint { - val referenceOwner = if (parent != null) { - val resolvedParent = parent.resolve(owner) - - if(resolvedParent is PropertyOwner) { - resolvedParent - } else { - raiseConcern("Accessing property of non-property-owner") { } - return CompositeConstraint() - } - } else { - owner - } - - val dereferencedConstraint = referenceOwner[identifier] - - return if (dereferencedConstraint != null && dereferencedConstraint !is ReferenceConstraint) { - if(dereferencedConstraint is PropertyOwner) { - modifiedProperties.forEach { (name, constraint) -> - //TODO take composite constraints into account here - dereferencedConstraint[name] = constraint - } - } - - dereferencedConstraint.resolve(referenceOwner) - } else { - this - } - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallResultConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallResultConstraint.kt deleted file mode 100644 index d649f2832..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallResultConstraint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.immutable.call - -import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint -import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner - -data class CallResultConstraint( - val callTarget: Constraint, - val arguments: List -) : ImmutableConstraint { //TODO treat this similarly to a reference constraint - override fun resolve(owner: PropertyOwner): Constraint { - val functionConstraint = callTarget.getResolvedFunctionConstraint(owner) - - return functionConstraint?.returnConstraints ?: VoidTypeConstraint - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt new file mode 100644 index 000000000..03227ef9a --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt @@ -0,0 +1,37 @@ +package org.jetbrains.dukat.js.type.constraint.reference + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.panic.raiseConcern + +abstract class PropertyOwnerReferenceConstraint : PropertyOwnerConstraint { + override val propertyNames: Set + get() = raiseConcern("Properties of a reference should never be listed.") { emptySet() } + + protected val modifiedProperties = LinkedHashMap() + + override fun set(name: String, data: Constraint) { + modifiedProperties[name] = data + } + + override fun get(name: String): Constraint { + return modifiedProperties[name] ?: ReferenceConstraint(IdentifierEntity(name), this) + } + + /** + * Called at resolving stage, + * to apply properties to the resolved reference. + */ + protected fun Constraint.resolveWithProperties(owner: PropertyOwner) : Constraint { + if(this is PropertyOwner) { + modifiedProperties.forEach { (name, constraint) -> + //TODO take composite constraints into account here + this[name] = constraint + } + } + + return this.resolve(owner) + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt new file mode 100644 index 000000000..6860b1e2f --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt @@ -0,0 +1,36 @@ +package org.jetbrains.dukat.js.type.constraint.reference + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.panic.raiseConcern + +open class ReferenceConstraint( + private val identifier: IdentifierEntity, + private val parent: PropertyOwnerConstraint? = null +) : PropertyOwnerReferenceConstraint() { + override fun resolve(owner: PropertyOwner): Constraint { + val referenceOwner = if (parent != null) { + val resolvedParent = parent.resolve(owner) + + if(resolvedParent is PropertyOwner) { + resolvedParent + } else { + raiseConcern("Accessing property of non-property-owner") { } + return CompositeConstraint() + } + } else { + owner + } + + val dereferencedConstraint = referenceOwner[identifier] + + return if (dereferencedConstraint != null && dereferencedConstraint !is ReferenceConstraint) { + dereferencedConstraint.resolveWithProperties(referenceOwner) + } else { + this + } + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallArgumentConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt similarity index 77% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallArgumentConstraint.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt index fb37bbb3e..f4cb67137 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/CallArgumentConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt @@ -1,14 +1,13 @@ -package org.jetbrains.dukat.js.type.constraint.immutable.call +package org.jetbrains.dukat.js.type.constraint.reference.call import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -data class CallArgumentConstraint( - val callTarget: Constraint, - val arguments: List, - val argumentNum: Int +class CallArgumentConstraint( + private val callTarget: Constraint, + private val argumentNum: Int ) : ImmutableConstraint { override fun resolve(owner: PropertyOwner): Constraint { val functionConstraint = callTarget.getResolvedFunctionConstraint(owner) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt new file mode 100644 index 000000000..3e355c37c --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt @@ -0,0 +1,15 @@ +package org.jetbrains.dukat.js.type.constraint.reference.call + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint +import org.jetbrains.dukat.js.type.constraint.reference.PropertyOwnerReferenceConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner + +class CallResultConstraint( + private val callTarget: Constraint +) : PropertyOwnerReferenceConstraint() { + override fun resolve(owner: PropertyOwner): Constraint { + val resultConstraint = callTarget.getResolvedFunctionConstraint(owner)?.returnConstraints ?: VoidTypeConstraint + return resultConstraint.resolveWithProperties(owner) + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/getResolvedFunction.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/getResolvedFunction.kt similarity index 76% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/getResolvedFunction.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/getResolvedFunction.kt index 6a071e422..24f133160 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/call/getResolvedFunction.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/getResolvedFunction.kt @@ -1,7 +1,6 @@ -package org.jetbrains.dukat.js.type.constraint.immutable.call +package org.jetbrains.dukat.js.type.constraint.reference.call import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt index b2ac6d36e..92d155b64 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt @@ -2,7 +2,7 @@ package org.jetbrains.dukat.js.type.property_owner import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.composite.ReferenceConstraint +import org.jetbrains.dukat.js.type.constraint.reference.ReferenceConstraint class Scope : PropertyOwner { override val propertyNames: Set From 630f75733ff8165d87871e51b431ed63edbfcd85 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 11:01:05 +0100 Subject: [PATCH 062/172] Add test to modify function result --- .../test/data/javascript/object/modified.d.kt | 37 +++++++++++++++++++ .../test/data/javascript/object/modified.d.ts | 15 ++++++++ 2 files changed, 52 insertions(+) create mode 100644 compiler/test/data/javascript/object/modified.d.kt create mode 100644 compiler/test/data/javascript/object/modified.d.ts diff --git a/compiler/test/data/javascript/object/modified.d.kt b/compiler/test/data/javascript/object/modified.d.kt new file mode 100644 index 000000000..5e7f24e02 --- /dev/null +++ b/compiler/test/data/javascript/object/modified.d.kt @@ -0,0 +1,37 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface `T$0` { + companion object { + var x: Number + var y: Number + } +} + +external fun get2DVector(): `T$0` + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface `T$1` { + companion object { + var x: Number + var y: Number + var z: Number + } +} + +external fun get3DVector(): `T$1` \ No newline at end of file diff --git a/compiler/test/data/javascript/object/modified.d.ts b/compiler/test/data/javascript/object/modified.d.ts new file mode 100644 index 000000000..be83a5d40 --- /dev/null +++ b/compiler/test/data/javascript/object/modified.d.ts @@ -0,0 +1,15 @@ + +function get2DVector() { + return { + x: 1, + y: 1 + } +} + +function get3DVector() { + var v2D = get2DVector() + + v2D.z = 1 + + return v2D +} \ No newline at end of file From bd566b7578bf5759f6af2f0564f408b2889192ee Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 11:28:10 +0100 Subject: [PATCH 063/172] Support functions with multiple return types --- .../test/data/javascript/conditional/if.d.kt | 6 +++-- .../test/data/javascript/conditional/if.d.ts | 4 +--- .../test/data/javascript/misc/random.d.kt | 4 ++-- .../dukat/js/type/analysis/introduceTypes.kt | 22 +++++++++++++++++-- .../composite/UnionTypeConstraint.kt | 13 +++++++++++ .../resolution/constraintToDeclaration.kt | 21 +++++++++++++----- 6 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt diff --git a/compiler/test/data/javascript/conditional/if.d.kt b/compiler/test/data/javascript/conditional/if.d.kt index b8a0d929d..baa5ac444 100644 --- a/compiler/test/data/javascript/conditional/if.d.kt +++ b/compiler/test/data/javascript/conditional/if.d.kt @@ -15,6 +15,8 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun max(a: Any?, b: Any?): Any? +external fun max(a: Any?, b: Any?): dynamic /* Any? */ -external fun negate(a: Number): Number \ No newline at end of file +external fun negate(a: Number): dynamic /* Number | Boolean */ + +external fun negate(a: Any?): dynamic /* Number | Boolean */ \ No newline at end of file diff --git a/compiler/test/data/javascript/conditional/if.d.ts b/compiler/test/data/javascript/conditional/if.d.ts index 63524874c..37b101d5d 100644 --- a/compiler/test/data/javascript/conditional/if.d.ts +++ b/compiler/test/data/javascript/conditional/if.d.ts @@ -9,8 +9,6 @@ function max(a, b) { function negate(a) { if(isNum(a)) return -a - else if(isBool(a)) - return !a else - return null + return !a } diff --git a/compiler/test/data/javascript/misc/random.d.kt b/compiler/test/data/javascript/misc/random.d.kt index 913f5b968..a5ef6c4de 100644 --- a/compiler/test/data/javascript/misc/random.d.kt +++ b/compiler/test/data/javascript/misc/random.d.kt @@ -17,9 +17,9 @@ import org.w3c.xhr.* external open class TestSet { open fun isElement(obj: Any?): Boolean - open fun isObject(obj: Any?): Boolean + open fun isObject(obj: Any?): dynamic /* Boolean */ open fun isArray(obj: Any?): Boolean - open fun isArrayLike(collection: Any?): Boolean + open fun isArrayLike(collection: Any?): dynamic /* Boolean */ open fun keyInObj(key: Any?, obj: Any?): Boolean open fun negate(predicate: Any?): Boolean } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index eb3b6e933..a0ec163d5 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -4,6 +4,7 @@ import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint @@ -53,9 +54,26 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) { )) } while (pathWalker.startNextPath()) - //TODO unify versions of function + owner[name] = if (versions.size == 1) { + versions[0] + } else { + val parameters = mutableListOf>>() - owner[name] = versions[0] + versions.forEach { + it.parameterConstraints.forEachIndexed { index, (name, constraint) -> + if (parameters.size <= index) { + parameters.add(index, name to mutableListOf()) + } + + parameters[index].second.add(constraint) + } + } + + FunctionConstraint( + returnConstraints = UnionTypeConstraint(versions.map { it.returnConstraints }), + parameterConstraints = parameters.map { (name, constraints) -> name to UnionTypeConstraint(constraints) } + ) + } } } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt new file mode 100644 index 000000000..137152ae4 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt @@ -0,0 +1,13 @@ +package org.jetbrains.dukat.js.type.constraint.composite + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner + +class UnionTypeConstraint( + val types: List +) : ImmutableConstraint { + override fun resolve(owner: PropertyOwner): Constraint { + return UnionTypeConstraint( types.map { it.resolve(owner) } ) + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index 68d035476..c9f6c208f 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -3,6 +3,7 @@ package org.jetbrains.dukat.js.type.constraint.resolution import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint @@ -28,6 +29,7 @@ import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration import org.jetbrains.dukat.tsmodel.types.TypeDeclaration +import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration val EXPORT_MODIFIERS = listOf(ModifierDeclaration.EXPORT_KEYWORD) val STATIC_MODIFIERS = listOf(ModifierDeclaration.STATIC_KEYWORD) @@ -51,7 +53,7 @@ fun getPropertyDeclaration(name: String, type: ParameterValueDeclaration, isStat fun Constraint.toParameterDeclaration(name: String) = ParameterDeclaration( name = name, - type = this.toType() ?: anyNullableType, + type = this.toType(), initializer = null, vararg = false, optional = false @@ -60,7 +62,7 @@ fun Constraint.toParameterDeclaration(name: String) = ParameterDeclaration( fun FunctionConstraint.toDeclaration(name: String) = FunctionDeclaration( name = name, parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, - type = returnConstraints.toType() ?: voidType, + type = returnConstraints.toType(), typeParameters = emptyList(), modifiers = EXPORT_MODIFIERS, body = null, @@ -78,7 +80,7 @@ fun FunctionConstraint.toMemberDeclaration(name: String, isStatic: Boolean) : Me fun Constraint.toMemberDeclaration(name: String, isStatic: Boolean = false) : MemberDeclaration? { return when (this) { is FunctionConstraint -> this.toMemberDeclaration(name, isStatic) - else -> this.toType()?.let { type -> getPropertyDeclaration(name, type, isStatic) } + else -> getPropertyDeclaration(name, this.toType(), isStatic) } } @@ -107,7 +109,13 @@ fun ClassConstraint.toDeclaration(name: String) : ClassDeclaration { ) } -fun ObjectConstraint.toType() : ObjectLiteralDeclaration? { +fun UnionTypeConstraint.toType() : UnionTypeDeclaration { + return UnionTypeDeclaration( + params = types.map { it.toType() } + ) +} + +fun ObjectConstraint.toType() : ObjectLiteralDeclaration { return ObjectLiteralDeclaration( members = propertyNames.mapNotNull { memberName -> this[memberName]?.toMemberDeclaration(name = memberName) @@ -116,13 +124,14 @@ fun ObjectConstraint.toType() : ObjectLiteralDeclaration? { ) } -fun Constraint.toType() : ParameterValueDeclaration? { +fun Constraint.toType() : ParameterValueDeclaration { return when (this) { is NumberTypeConstraint -> numberType is BigIntTypeConstraint -> numberType is BooleanTypeConstraint -> booleanType is StringTypeConstraint -> stringType is VoidTypeConstraint -> voidType + is UnionTypeConstraint -> this.toType() is ObjectConstraint -> this.toType() else -> anyNullableType } @@ -133,6 +142,6 @@ fun Constraint.toDeclaration(name: String) : TopLevelDeclaration? { is ClassConstraint -> this.toDeclaration(name) is FunctionConstraint -> this.toDeclaration(name) is CompositeConstraint -> raiseConcern("Unexpected composited type for variable named '$name'. Should be resolved by this point!") { null } - else -> this.toType()?.let { type -> getVariableDeclaration(name, type) } + else -> getVariableDeclaration(name, this.toType()) } } \ No newline at end of file From 7db1f54c5520324447b364dedb6bca24bdb9891c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 13:01:28 +0100 Subject: [PATCH 064/172] Add block statement --- typescript/ts-converter/src/AstConverter.ts | 29 ++++++++++++++----- typescript/ts-converter/src/ast/AstFactory.ts | 8 +++++ .../ts-model-proto/src/Declarations.proto | 1 + .../dukat/tsmodel/factory/convertProtobuf.kt | 1 + 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index 521061533..c9fe55362 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -171,22 +171,32 @@ export class AstConverter { return typeParameterDeclarations; } - convertBlock(block: ts.Block): Block | null { - if (block) { - const statements: Declaration[] = []; + private getStatementsFromBlock(block: ts.Block): Array { + let statements: Declaration[] = []; - for (let statement of block.statements) { - for (let decl of this.convertTopLevelStatement(statement)) { - this.registerDeclaration(decl, statements) - } + for (let statement of block.statements) { + for (let decl of this.convertTopLevelStatement(statement)) { + this.registerDeclaration(decl, statements) } + } + + return statements; + } + convertBlock(block: ts.Block | null): Block | null { + if (block) { + let statements = this.getStatementsFromBlock(block); return this.astFactory.createBlockDeclaration(statements); } else { return null; } } + convertBlockStatement(block: ts.Block): Block { + let statements = this.getStatementsFromBlock(block); + return this.astFactory.createBlockStatementDeclaration(statements); + } + convertFunctionDeclaration(functionDeclaration: ts.FunctionDeclaration): FunctionDeclaration | null { let typeParameterDeclarations: Array = this.convertTypeParams(functionDeclaration.typeParameters); @@ -791,6 +801,11 @@ export class AstConverter { this.convertTopLevelStatement(statement.thenStatement), this.convertTopLevelStatement(statement.elseStatement) )) + } else if (ts.isBlock(statement)) { + let block = this.convertBlockStatement(statement); + if (block) { + res.push(block) + } } else if (ts.isReturnStatement(statement)) { let expression : Expression | null = null; if (statement.expression) { diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index c00d9d9ee..564d3b700 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -161,6 +161,14 @@ export class AstFactory implements AstFactory { return block } + createBlockStatementDeclaration(statements: Array): Block { + let block = this.createBlockDeclaration(statements); + + let topLevelEntity = new declarations.TopLevelEntityProto(); + topLevelEntity.setBlockstatement(block); + return topLevelEntity; + } + private createFunctionDeclaration(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, body: Block | null, uid: String): ProtoMessage { let functionDeclaration = new declarations.FunctionDeclarationProto(); functionDeclaration.setName(name); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 60ef776f0..b076ee179 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -343,6 +343,7 @@ message TopLevelEntityProto { ExpressionStatementDeclarationProto expressionStatement = 10; ReturnStatementDeclarationProto returnStatement = 11; IfStatementDeclarationProto ifStatement = 12; + BlockDeclarationProto blockStatement = 13; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 111acdff5..1e8e2f41f 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -236,6 +236,7 @@ fun Declarations.TopLevelEntityProto.convert(): TopLevelDeclaration { hasIfStatement() -> ifStatement.convert() hasExpressionStatement() -> expressionStatement.convert() hasReturnStatement() -> returnStatement.convert() + hasBlockStatement() -> blockStatement.convert() else -> throw Exception("unknown TopLevelEntity: ${this}") } } From 6c904722db7ea8c815e95aab3c5ca38ddc9e668b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 13:08:24 +0100 Subject: [PATCH 065/172] Add block as 'then' and 'else' statements in conditional test --- compiler/test/data/javascript/conditional/if.d.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/test/data/javascript/conditional/if.d.ts b/compiler/test/data/javascript/conditional/if.d.ts index 37b101d5d..90068b413 100644 --- a/compiler/test/data/javascript/conditional/if.d.ts +++ b/compiler/test/data/javascript/conditional/if.d.ts @@ -7,8 +7,9 @@ function max(a, b) { } function negate(a) { - if(isNum(a)) + if(isNum(a)) { return -a - else + } else { return !a + } } From 0d7c010a3c77aac31206ed7f7496281f3dac8618 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 13:13:40 +0100 Subject: [PATCH 066/172] Fix crash when else-statement in if-statement doesn't exist --- typescript/ts-converter/src/AstConverter.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index c9fe55362..b7499da34 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -796,10 +796,18 @@ export class AstConverter { this.astExpressionConverter.convertExpression(statement.expression) )); } else if (ts.isIfStatement(statement)) { + let elseStatement; + + if (statement.elseStatement) { + elseStatement = this.convertTopLevelStatement(statement.elseStatement) + } else { + elseStatement = null + } + res.push(this.astFactory.createIfStatement( this.astExpressionConverter.convertExpression(statement.expression), this.convertTopLevelStatement(statement.thenStatement), - this.convertTopLevelStatement(statement.elseStatement) + elseStatement )) } else if (ts.isBlock(statement)) { let block = this.convertBlockStatement(statement); From 62099c8f500e24f974a955b86799ddb7c143e6b9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 13:17:53 +0100 Subject: [PATCH 067/172] Change conditional test to include if-statement without else-block --- compiler/test/data/javascript/conditional/if.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/test/data/javascript/conditional/if.d.ts b/compiler/test/data/javascript/conditional/if.d.ts index 90068b413..e410eb446 100644 --- a/compiler/test/data/javascript/conditional/if.d.ts +++ b/compiler/test/data/javascript/conditional/if.d.ts @@ -2,8 +2,8 @@ function max(a, b) { if (a > b) return a - else - return b + + return b } function negate(a) { From 476185e4f2093b861bd222aed074c2189f745ca7 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 14:19:10 +0100 Subject: [PATCH 068/172] Properly resolve property access to expressions other than identifiers and property access expressions --- .../test/data/javascript/misc/random.d.ts | 129 +++++++++--------- .../dukat/js/type/analysis/expression.kt | 34 +++-- .../reference/ReferenceConstraint.kt | 1 + .../js/type/property_owner/PropertyOwner.kt | 18 +-- 4 files changed, 98 insertions(+), 84 deletions(-) diff --git a/compiler/test/data/javascript/misc/random.d.ts b/compiler/test/data/javascript/misc/random.d.ts index c7ad91f3e..3ea14a506 100644 --- a/compiler/test/data/javascript/misc/random.d.ts +++ b/compiler/test/data/javascript/misc/random.d.ts @@ -1,78 +1,79 @@ -class TestSet { - isElement(obj) { - return !!(obj && obj.nodeType === 1); +class _ { + // ??? + // Retrieve the values of an object's properties. + // Array + static values(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; } - isObject(obj) { - var type = typeof obj; - return type === 'function' || type === 'object' && !!obj; - } + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native Object.keys. + static keys(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + static negate(predicate) { + return !predicate.apply(this, arguments); + }; - isArray(obj) { + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + static isArray(obj) { return toString.call(obj) === '[object Array]'; } - isArrayLike(collection) { - var length = getLength(collection); - return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + // Is a given variable an object? + static isObject(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; } - keyInObj(key, obj) { - return key in obj; + // Is a given value a DOM element? + static isElement(obj) { + return !!(obj && obj.nodeType === 1); } - //Originally returns a function (this was skipped for testing) - negate(predicate) { - return !predicate.apply(this, arguments); + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + static isEmpty(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; } + +} + + + +// Internal pick helper function to determine if obj has key key. +function keyInObj(value, key, obj) { + return key in obj; } -/* -// ??? -// Retrieve the values of an object's properties. -// Array -export _.values = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[keys[i]]; - } - return values; -}; -// Retrieve the names of an object's own properties. -// Delegates to **ECMAScript 5**'s native Object.keys. -_.keys = function(obj) { - if (!_.isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (has(obj, key)) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; -}; // Generator function to create the findIndex and findLastIndex functions. -var createPredicateIndexFinder = function(dir) { - return function(array, predicate, context) { - predicate = cb(predicate, context); - var length = getLength(array); - var index = dir > 0 ? 0 : length - 1; - for (; index >= 0 && index < length; index += dir) { - if (predicate(array[index], index, array)) return index; - } - return -1; - }; -}; -_.negate = function(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; -}; -// Is a given array, string, or object empty? -// An "empty" object has no enumerable own-properties. -_.isEmpty = function(obj) { - if (obj == null) return true; isEmpty1 => boolean - if (isArrayLike(obj) && (.isArray(obj) || .isString(obj) || _.isArguments(obj))) return obj.length === 0; isEmpty2 => boolean - return _.keys(obj).length === 0; isEmpty3 => boolean -}; -*/ \ No newline at end of file +function createPredicateIndexFinder(array, predicate, context, dir) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; +} + +function isArrayLike(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; +} diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index b7256d0aa..3ecc0e976 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -28,40 +28,50 @@ import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDec import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { - val rightConstraints = right.calculateConstraints(owner, path) - val leftConstraints = left.calculateConstraints(owner, path) - return when (operator) { // Assignments "=" -> { - owner[left] = rightConstraints + val rightConstraints = right.calculateConstraints(owner, path) + owner[left, path] = rightConstraints rightConstraints } "-=", "*=", "/=", "%=", "**=", "&=", "^=", "|=", "<<=", ">>=", ">>>=" -> { - owner[left] = NumberTypeConstraint + right.calculateConstraints(owner, path) + owner[left, path] = NumberTypeConstraint NumberTypeConstraint } // Non-assignments "&&", "||" -> { - //TODO only calculate the constraints of the chosen path with this operator when (path.getNextDirection()) { - PathWalker.Direction.First -> leftConstraints - PathWalker.Direction.Second -> rightConstraints + PathWalker.Direction.First -> { + left.calculateConstraints(owner, path) + //right isn't be evaluated + } + PathWalker.Direction.Second -> { + left.calculateConstraints(owner, path) + right.calculateConstraints(owner, path) + } } } "-", "*", "/", "**", "%", "++", "--" -> { - rightConstraints += NumberTypeConstraint - leftConstraints += NumberTypeConstraint + left.calculateConstraints(owner, path) += NumberTypeConstraint + right.calculateConstraints(owner, path) += NumberTypeConstraint NumberTypeConstraint } "&", "|", "^", "<<", ">>", ">>>" -> { + left.calculateConstraints(owner, path) + right.calculateConstraints(owner, path) NumberTypeConstraint } "==", "===", "!=", "!==", ">", "<", ">=", "<=", "in", "instanceof" -> { + left.calculateConstraints(owner, path) + right.calculateConstraints(owner, path) BooleanTypeConstraint } else -> { + left.calculateConstraints(owner, path) + right.calculateConstraints(owner, path) CompositeConstraint(NoTypeConstraint) } } @@ -73,7 +83,7 @@ fun UnaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: return when (operator) { "--", "++", "~" -> { operandConstraints += NumberTypeConstraint - owner[operand] = NumberTypeConstraint + owner[operand, path] = NumberTypeConstraint NumberTypeConstraint } "-", "+" -> { @@ -130,7 +140,7 @@ fun LiteralExpressionDeclaration.calculateConstraints(path: PathWalker) : Constr fun ExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { return when (this) { is IdentifierExpressionDeclaration -> owner[this] ?: ReferenceConstraint(this.identifier) - is PropertyAccessExpressionDeclaration -> owner[this] ?: CompositeConstraint() //TODO replace this with a reference constraint (of some sort) + is PropertyAccessExpressionDeclaration -> owner[this, path] ?: CompositeConstraint() //TODO replace this with a reference constraint (of some sort) is BinaryExpressionDeclaration -> this.calculateConstraints(owner, path) is UnaryExpressionDeclaration -> this.calculateConstraints(owner, path) is TypeOfExpressionDeclaration -> this.calculateConstraints(owner, path) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt index 6860b1e2f..3f21476de 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt @@ -25,6 +25,7 @@ open class ReferenceConstraint( owner } + println(identifier.value) val dereferencedConstraint = referenceOwner[identifier] return if (dereferencedConstraint != null && dereferencedConstraint !is ReferenceConstraint) { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt index 2c4b5e151..dec881b10 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt @@ -1,6 +1,8 @@ package org.jetbrains.dukat.js.type.property_owner import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.js.type.analysis.PathWalker +import org.jetbrains.dukat.js.type.analysis.calculateConstraints import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration @@ -20,18 +22,18 @@ interface PropertyOwner { this[identifierExpression.identifier] = data } - operator fun set(propertyAccessExpression: PropertyAccessExpressionDeclaration, data: Constraint) { - val base = this[propertyAccessExpression.expression] + operator fun set(propertyAccessExpression: PropertyAccessExpressionDeclaration, path: PathWalker, data: Constraint) { + val base = propertyAccessExpression.expression.calculateConstraints(this, path) if (base is PropertyOwner) { base[propertyAccessExpression.name] = data } } - operator fun set(expression: ExpressionDeclaration, data: Constraint) { + operator fun set(expression: ExpressionDeclaration, path: PathWalker, data: Constraint) { when (expression) { is IdentifierExpressionDeclaration -> this[expression] = data - is PropertyAccessExpressionDeclaration -> this[expression] = data + is PropertyAccessExpressionDeclaration -> this[expression, path] = data else -> raiseConcern("Cannot set variable described by expression of type <${expression::class}>") { } } } @@ -68,8 +70,8 @@ interface PropertyOwner { return this[identifierExpression.identifier] } - operator fun get(propertyAccessExpression: PropertyAccessExpressionDeclaration) : Constraint? { - val base = this[propertyAccessExpression.expression] + operator fun get(propertyAccessExpression: PropertyAccessExpressionDeclaration, path: PathWalker) : Constraint? { + val base = propertyAccessExpression.expression.calculateConstraints(this, path) return if (base is PropertyOwner) { base[propertyAccessExpression.name] @@ -78,10 +80,10 @@ interface PropertyOwner { } } - operator fun get(expression: ExpressionDeclaration) : Constraint? { + operator fun get(expression: ExpressionDeclaration, path: PathWalker) : Constraint? { return when (expression) { is IdentifierExpressionDeclaration -> this[expression] - is PropertyAccessExpressionDeclaration -> this[expression] + is PropertyAccessExpressionDeclaration -> this[expression, path] else -> raiseConcern("Cannot get variable described by expression of type <${expression::class}>") { null } } } From 4d4eb94a85b2411019d40b52a44882a2da7f58c7 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 17:10:28 +0100 Subject: [PATCH 069/172] Simplify test --- .../test/data/javascript/misc/random.d.kt | 37 +++++-- .../test/data/javascript/misc/random.d.ts | 104 +++++++++--------- 2 files changed, 83 insertions(+), 58 deletions(-) diff --git a/compiler/test/data/javascript/misc/random.d.kt b/compiler/test/data/javascript/misc/random.d.kt index a5ef6c4de..375c9c405 100644 --- a/compiler/test/data/javascript/misc/random.d.kt +++ b/compiler/test/data/javascript/misc/random.d.kt @@ -15,11 +15,32 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external open class TestSet { - open fun isElement(obj: Any?): Boolean - open fun isObject(obj: Any?): dynamic /* Boolean */ - open fun isArray(obj: Any?): Boolean - open fun isArrayLike(collection: Any?): dynamic /* Boolean */ - open fun keyInObj(key: Any?, obj: Any?): Boolean - open fun negate(predicate: Any?): Boolean -} \ No newline at end of file +external object _ { + fun values(obj: Any?) + fun keys(obj: dynamic /* Any? */): dynamic /* Any? */ + fun negate(predicate: Any?): Boolean + fun isArray(obj: Any?): Boolean + fun isObject(obj: dynamic /* Any? */): dynamic /* Boolean */ + fun isElement(obj: Any?): Boolean + fun isEmpty(obj: dynamic /* Any? */): dynamic /* Boolean */ +} + +external fun values(obj: Any?) + +external fun keys(obj: Any?): dynamic /* Any? | Unit */ + +external fun negate(predicate: Any?): Boolean + +external fun isArray(obj: Any?): Boolean + +external fun isObject(obj: Any?): dynamic /* Boolean */ + +external fun isElement(obj: Any?): Boolean + +external fun isEmpty(obj: Any?): dynamic /* Boolean */ + +external fun keyInObj(value: Any?, key: Any?, obj: Any?): Boolean + +external fun createPredicateIndexFinder(array: Any?, predicate: Any?, context: Any?, dir: Any?): Number + +external fun isArrayLike(collection: Any?): dynamic /* Boolean */ \ No newline at end of file diff --git a/compiler/test/data/javascript/misc/random.d.ts b/compiler/test/data/javascript/misc/random.d.ts index 3ea14a506..7a1704d5b 100644 --- a/compiler/test/data/javascript/misc/random.d.ts +++ b/compiler/test/data/javascript/misc/random.d.ts @@ -1,61 +1,65 @@ -class _ { - // ??? - // Retrieve the values of an object's properties. - // Array - static values(obj) { - var keys = _.keys(obj); - var length = keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[keys[i]]; - } - return values; - } - - // Retrieve the names of an object's own properties. - // Delegates to **ECMAScript 5**'s native Object.keys. - static keys(obj) { - if (!_.isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (has(obj, key)) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; - }; +let _ = {} - static negate(predicate) { - return !predicate.apply(this, arguments); - }; - - // Is a given value an array? - // Delegates to ECMA5's native Array.isArray - static isArray(obj) { - return toString.call(obj) === '[object Array]'; +// ??? +// Retrieve the values of an object's properties. +// Array +function values(obj) { + var keys = keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; } + return values; +} +_.values = values - // Is a given variable an object? - static isObject(obj) { - var type = typeof obj; - return type === 'function' || type === 'object' && !!obj; - } +// Retrieve the names of an object's own properties. +// Delegates to **ECMAScript 5**'s native Object.keys. +function keys(obj) { + if (!isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; +} +_.keys = keys - // Is a given value a DOM element? - static isElement(obj) { - return !!(obj && obj.nodeType === 1); - } +function negate(predicate) { + return !predicate.apply(this, arguments); +} +_.negate = negate - // Is a given array, string, or object empty? - // An "empty" object has no enumerable own-properties. - static isEmpty(obj) { - if (obj == null) return true; - if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; - return _.keys(obj).length === 0; - } +// Is a given value an array? +// Delegates to ECMA5's native Array.isArray +function isArray(obj) { + return toString.call(obj) === '[object Array]'; +} +_.isArray = isArray +// Is a given variable an object? +function isObject(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; } +_.isObject = isObject +// Is a given value a DOM element? +function isElement(obj) { + return !!(obj && obj.nodeType === 1); +} +_.isElement = isElement +// Is a given array, string, or object empty? +// An "empty" object has no enumerable own-properties. +function isEmpty(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (isArray(obj) || isString(obj) || isArguments(obj))) return obj.length === 0; + return keys(obj).length === 0; +} +_.isEmpty = isEmpty // Internal pick helper function to determine if obj has key key. function keyInObj(value, key, obj) { @@ -76,4 +80,4 @@ function createPredicateIndexFinder(array, predicate, context, dir) { function isArrayLike(collection) { var length = getLength(collection); return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; -} +} \ No newline at end of file From a71952d4b8ff13a0bb4a59ddc5f6d4db3ca0b92b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 17:10:46 +0100 Subject: [PATCH 070/172] Remove debug output --- .../dukat/js/type/constraint/reference/ReferenceConstraint.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt index 3f21476de..6860b1e2f 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt @@ -25,7 +25,6 @@ open class ReferenceConstraint( owner } - println(identifier.value) val dereferencedConstraint = referenceOwner[identifier] return if (dereferencedConstraint != null && dereferencedConstraint !is ReferenceConstraint) { From ce36ba3eca5b7994d23c6ff4a900c810064e5e10 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 17:38:10 +0100 Subject: [PATCH 071/172] Make union type with single type not dynamic (use the single type instead) --- .../test/data/javascript/conditional/if.d.kt | 2 +- .../test/data/javascript/misc/random.d.kt | 12 ++++---- .../nodeLowering/lowerings/introduceModels.kt | 28 +++++++++++-------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/compiler/test/data/javascript/conditional/if.d.kt b/compiler/test/data/javascript/conditional/if.d.kt index baa5ac444..0cdcf086d 100644 --- a/compiler/test/data/javascript/conditional/if.d.kt +++ b/compiler/test/data/javascript/conditional/if.d.kt @@ -15,7 +15,7 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun max(a: Any?, b: Any?): dynamic /* Any? */ +external fun max(a: Any?, b: Any?): Any? external fun negate(a: Number): dynamic /* Number | Boolean */ diff --git a/compiler/test/data/javascript/misc/random.d.kt b/compiler/test/data/javascript/misc/random.d.kt index 375c9c405..fffb8a4b3 100644 --- a/compiler/test/data/javascript/misc/random.d.kt +++ b/compiler/test/data/javascript/misc/random.d.kt @@ -17,12 +17,12 @@ import org.w3c.xhr.* external object _ { fun values(obj: Any?) - fun keys(obj: dynamic /* Any? */): dynamic /* Any? */ + fun keys(obj: Any?): dynamic /* Any? | Unit */ fun negate(predicate: Any?): Boolean fun isArray(obj: Any?): Boolean - fun isObject(obj: dynamic /* Any? */): dynamic /* Boolean */ + fun isObject(obj: Any?): Boolean fun isElement(obj: Any?): Boolean - fun isEmpty(obj: dynamic /* Any? */): dynamic /* Boolean */ + fun isEmpty(obj: Any?): Boolean } external fun values(obj: Any?) @@ -33,14 +33,14 @@ external fun negate(predicate: Any?): Boolean external fun isArray(obj: Any?): Boolean -external fun isObject(obj: Any?): dynamic /* Boolean */ +external fun isObject(obj: Any?): Boolean external fun isElement(obj: Any?): Boolean -external fun isEmpty(obj: Any?): dynamic /* Boolean */ +external fun isEmpty(obj: Any?): Boolean external fun keyInObj(value: Any?, key: Any?, obj: Any?): Boolean external fun createPredicateIndexFinder(array: Any?, predicate: Any?, context: Any?, dir: Any?): Number -external fun isArrayLike(collection: Any?): dynamic /* Boolean */ \ No newline at end of file +external fun isArrayLike(collection: Any?): Boolean \ No newline at end of file diff --git a/typescript/ts-node-lowering/src/org/jetrbains/dukat/nodeLowering/lowerings/introduceModels.kt b/typescript/ts-node-lowering/src/org/jetrbains/dukat/nodeLowering/lowerings/introduceModels.kt index 2c6f5e22c..4c775cb7a 100644 --- a/typescript/ts-node-lowering/src/org/jetrbains/dukat/nodeLowering/lowerings/introduceModels.kt +++ b/typescript/ts-node-lowering/src/org/jetrbains/dukat/nodeLowering/lowerings/introduceModels.kt @@ -212,17 +212,23 @@ private fun TranslationContext.resolveAsMetaOptions(): Set { private fun ParameterValueDeclaration.process(context: TranslationContext = TranslationContext.IRRELEVANT): TypeModel { return when (this) { - is UnionTypeNode -> TypeValueModel( - IdentifierEntity("dynamic"), - emptyList(), - params.map { unionMember -> - if (unionMember.meta is StringLiteralDeclaration) { - (unionMember.meta as StringLiteralDeclaration).token - } else { - unionMember.process().translate() - } - }.joinToString(" | ") - ) + is UnionTypeNode -> { + if (params.size == 1) { + params[0].process(context) + } else { + TypeValueModel( + IdentifierEntity("dynamic"), + emptyList(), + params.map { unionMember -> + if (unionMember.meta is StringLiteralDeclaration) { + (unionMember.meta as StringLiteralDeclaration).token + } else { + unionMember.process().translate() + } + }.joinToString(" | ") + ) + } + } is TupleTypeNode -> TypeValueModel( IdentifierEntity("dynamic"), emptyList(), From d3c5c5336d75dd779032954a35e5851c7fd1cc8b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 17:55:46 +0100 Subject: [PATCH 072/172] Change unknown types to Any?, instead of Unit --- compiler/test/data/javascript/misc/random.d.kt | 8 ++++---- .../test/data/javascript/reference/undefined.d.kt | 2 +- .../dukat/js/type/analysis/introduceTypes.kt | 5 +++-- .../reference/call/CallArgumentConstraint.kt | 13 +++++++++---- .../reference/call/CallResultConstraint.kt | 11 ++++++++--- .../reference/call/getResolvedFunction.kt | 12 ------------ 6 files changed, 25 insertions(+), 26 deletions(-) delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/getResolvedFunction.kt diff --git a/compiler/test/data/javascript/misc/random.d.kt b/compiler/test/data/javascript/misc/random.d.kt index fffb8a4b3..204c9bb5f 100644 --- a/compiler/test/data/javascript/misc/random.d.kt +++ b/compiler/test/data/javascript/misc/random.d.kt @@ -16,8 +16,8 @@ import org.w3c.workers.* import org.w3c.xhr.* external object _ { - fun values(obj: Any?) - fun keys(obj: Any?): dynamic /* Any? | Unit */ + fun values(obj: Any?): Any? + fun keys(obj: Any?): Any? fun negate(predicate: Any?): Boolean fun isArray(obj: Any?): Boolean fun isObject(obj: Any?): Boolean @@ -25,9 +25,9 @@ external object _ { fun isEmpty(obj: Any?): Boolean } -external fun values(obj: Any?) +external fun values(obj: Any?): Any? -external fun keys(obj: Any?): dynamic /* Any? | Unit */ +external fun keys(obj: Any?): Any? external fun negate(predicate: Any?): Boolean diff --git a/compiler/test/data/javascript/reference/undefined.d.kt b/compiler/test/data/javascript/reference/undefined.d.kt index 3662d5832..e916a4608 100644 --- a/compiler/test/data/javascript/reference/undefined.d.kt +++ b/compiler/test/data/javascript/reference/undefined.d.kt @@ -15,4 +15,4 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun undefReferenceFun() \ No newline at end of file +external fun undefReferenceFun(): Any? \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index a0ec163d5..0528ea91d 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -6,6 +6,7 @@ import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner @@ -86,7 +87,7 @@ fun InterfaceDeclaration.addTo(owner: PropertyOwner) */ fun PropertyDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { - owner[name] = initializer?.calculateConstraints(owner, path) ?: VoidTypeConstraint + owner[name] = initializer?.calculateConstraints(owner, path) ?: NoTypeConstraint } fun MemberDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { @@ -123,7 +124,7 @@ fun BlockDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker } fun VariableDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { - owner[name] = initializer?.calculateConstraints(owner, path) ?: VoidTypeConstraint + owner[name] = initializer?.calculateConstraints(owner, path) ?: NoTypeConstraint } fun IfStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt index f4cb67137..ddc1f5d33 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt @@ -3,6 +3,7 @@ package org.jetbrains.dukat.js.type.constraint.reference.call import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class CallArgumentConstraint( @@ -10,12 +11,16 @@ class CallArgumentConstraint( private val argumentNum: Int ) : ImmutableConstraint { override fun resolve(owner: PropertyOwner): Constraint { - val functionConstraint = callTarget.getResolvedFunctionConstraint(owner) + val functionConstraint = callTarget.resolve(owner) - return if (functionConstraint != null && functionConstraint.parameterConstraints.size >= argumentNum) { - return functionConstraint.parameterConstraints[argumentNum].second + return if (functionConstraint is FunctionConstraint) { + if (functionConstraint.parameterConstraints.size >= argumentNum) { + functionConstraint.parameterConstraints[argumentNum].second + } else { + CompositeConstraint() + } } else { - CompositeConstraint() + CallArgumentConstraint(functionConstraint, argumentNum) } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt index 3e355c37c..60e1f0bc5 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt @@ -1,7 +1,7 @@ package org.jetbrains.dukat.js.type.constraint.reference.call import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint +import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.constraint.reference.PropertyOwnerReferenceConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner @@ -9,7 +9,12 @@ class CallResultConstraint( private val callTarget: Constraint ) : PropertyOwnerReferenceConstraint() { override fun resolve(owner: PropertyOwner): Constraint { - val resultConstraint = callTarget.getResolvedFunctionConstraint(owner)?.returnConstraints ?: VoidTypeConstraint - return resultConstraint.resolveWithProperties(owner) + val functionConstraint = callTarget.resolve(owner) + + return if (functionConstraint is FunctionConstraint) { + functionConstraint.returnConstraints.resolveWithProperties(owner) + } else { + CallResultConstraint(functionConstraint) + } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/getResolvedFunction.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/getResolvedFunction.kt deleted file mode 100644 index 24f133160..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/getResolvedFunction.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.reference.call - -import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint - -internal fun Constraint.getResolvedFunctionConstraint(owner: PropertyOwner) : FunctionConstraint? { - return when (val resolvedCallTarget = this.resolve(owner)) { - is FunctionConstraint -> resolvedCallTarget - else -> null - } -} \ No newline at end of file From 1d5147d1a07899a0bf67bf6e8ad95da93ef71e64 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2019 18:26:41 +0100 Subject: [PATCH 073/172] Allow functions as return types --- .../test/data/javascript/function/asType.d.kt | 20 +++++++++++++++++++ .../test/data/javascript/function/asType.d.ts | 8 ++++++++ .../resolution/constraintToDeclaration.kt | 10 +++++++++- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 compiler/test/data/javascript/function/asType.d.kt create mode 100644 compiler/test/data/javascript/function/asType.d.ts diff --git a/compiler/test/data/javascript/function/asType.d.kt b/compiler/test/data/javascript/function/asType.d.kt new file mode 100644 index 000000000..2736e3ac3 --- /dev/null +++ b/compiler/test/data/javascript/function/asType.d.kt @@ -0,0 +1,20 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun minus(a: Number, b: Number): Number + +external fun getMinus(): (a: Number, b: Number) -> Number \ No newline at end of file diff --git a/compiler/test/data/javascript/function/asType.d.ts b/compiler/test/data/javascript/function/asType.d.ts new file mode 100644 index 000000000..f09e9534f --- /dev/null +++ b/compiler/test/data/javascript/function/asType.d.ts @@ -0,0 +1,8 @@ + +function minus(a, b) { + return a - b +} + +function getMinus() { + return minus +} diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index c9f6c208f..3e7fab69c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -26,9 +26,9 @@ import org.jetbrains.dukat.tsmodel.ParameterDeclaration import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration +import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration -import org.jetbrains.dukat.tsmodel.types.TypeDeclaration import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration val EXPORT_MODIFIERS = listOf(ModifierDeclaration.EXPORT_KEYWORD) @@ -109,6 +109,13 @@ fun ClassConstraint.toDeclaration(name: String) : ClassDeclaration { ) } +fun FunctionConstraint.toType() : FunctionTypeDeclaration { + return FunctionTypeDeclaration( + parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, + type = returnConstraints.toType() + ) +} + fun UnionTypeConstraint.toType() : UnionTypeDeclaration { return UnionTypeDeclaration( params = types.map { it.toType() } @@ -133,6 +140,7 @@ fun Constraint.toType() : ParameterValueDeclaration { is VoidTypeConstraint -> voidType is UnionTypeConstraint -> this.toType() is ObjectConstraint -> this.toType() + is FunctionConstraint -> this.toType() else -> anyNullableType } } From b6dbe6911b28159342c3f28137636c3d51d9b966 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Nov 2019 11:47:50 +0100 Subject: [PATCH 074/172] Block function branches, in which they execute themselves, from being resolved. --- .../test/data/javascript/misc/random.d.ts | 8 +++---- .../data/javascript/reference/recursive.d.kt | 20 +++++++++++++++++ .../data/javascript/reference/recursive.d.ts | 7 ++++++ .../immutable/resolved/RecursiveConstraint.kt | 3 +++ .../properties/FunctionConstraint.kt | 22 +++++++++++++++---- 5 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 compiler/test/data/javascript/reference/recursive.d.kt create mode 100644 compiler/test/data/javascript/reference/recursive.d.ts create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/RecursiveConstraint.kt diff --git a/compiler/test/data/javascript/misc/random.d.ts b/compiler/test/data/javascript/misc/random.d.ts index 7a1704d5b..7bd666c5e 100644 --- a/compiler/test/data/javascript/misc/random.d.ts +++ b/compiler/test/data/javascript/misc/random.d.ts @@ -4,7 +4,7 @@ let _ = {} // Retrieve the values of an object's properties. // Array function values(obj) { - var keys = keys(obj); + var keys = _.keys(obj); var length = keys.length; var values = Array(length); for (var i = 0; i < length; i++) { @@ -17,7 +17,7 @@ _.values = values // Retrieve the names of an object's own properties. // Delegates to **ECMAScript 5**'s native Object.keys. function keys(obj) { - if (!isObject(obj)) return []; + if (!_.isObject(obj)) return []; if (nativeKeys) return nativeKeys(obj); var keys = []; for (var key in obj) if (has(obj, key)) keys.push(key); @@ -56,8 +56,8 @@ _.isElement = isElement // An "empty" object has no enumerable own-properties. function isEmpty(obj) { if (obj == null) return true; - if (isArrayLike(obj) && (isArray(obj) || isString(obj) || isArguments(obj))) return obj.length === 0; - return keys(obj).length === 0; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; } _.isEmpty = isEmpty diff --git a/compiler/test/data/javascript/reference/recursive.d.kt b/compiler/test/data/javascript/reference/recursive.d.kt new file mode 100644 index 000000000..a2f8c83df --- /dev/null +++ b/compiler/test/data/javascript/reference/recursive.d.kt @@ -0,0 +1,20 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun fibonacci(num: Any?): dynamic /* Number | Any? */ + +external fun fibonacci(num: Number): dynamic /* Number | Any? */ \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/recursive.d.ts b/compiler/test/data/javascript/reference/recursive.d.ts new file mode 100644 index 000000000..01933983c --- /dev/null +++ b/compiler/test/data/javascript/reference/recursive.d.ts @@ -0,0 +1,7 @@ + +//The solution to this isn't pretty, but it's better than nothing! +function fibonacci(num) { + if (num <= 1) return 1; + + return fibonacci(num - 1) + fibonacci(num - 2); +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/RecursiveConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/RecursiveConstraint.kt new file mode 100644 index 000000000..d1115e1d5 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/RecursiveConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.immutable.resolved + +object RecursiveConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt index dd9062a2e..1464bc617 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt @@ -2,16 +2,30 @@ package org.jetbrains.dukat.js.type.constraint.properties import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class FunctionConstraint( val returnConstraints: Constraint, val parameterConstraints: List> ) : ImmutableConstraint { //TODO make property owner (since functions technically are, in javascript) + private var isResolving = false + override fun resolve(owner: PropertyOwner): FunctionConstraint { - return FunctionConstraint( - returnConstraints.resolve(owner), - parameterConstraints.map { (name, constraint) -> name to constraint.resolve(owner) } - ) + if (!isResolving) { + isResolving = true + val resolvedConstraint = FunctionConstraint( + returnConstraints.resolve(owner), + parameterConstraints.map { (name, constraint) -> name to constraint.resolve(owner) } + ) + isResolving = false + return resolvedConstraint + } else { + return FunctionConstraint( + RecursiveConstraint, + parameterConstraints.map { (name, _) -> name to NoTypeConstraint } + ) + } } } \ No newline at end of file From 86d8604ef235452c403b507cc10083f88b6216d1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Nov 2019 13:02:45 +0100 Subject: [PATCH 075/172] Remove recursive constraints at resolution --- .../type/constraint/composite/CompositeConstraint.kt | 2 ++ .../type/constraint/composite/UnionTypeConstraint.kt | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt index a9d50afa1..1f4b8b37c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt @@ -5,6 +5,7 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConst import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import javax.lang.model.type.NoType @@ -39,6 +40,7 @@ class CompositeConstraint(private val constraints: MutableSet) : Con resolvedConstraints.contains(BigIntTypeConstraint) -> BigIntTypeConstraint resolvedConstraints.contains(BooleanTypeConstraint) -> BooleanTypeConstraint resolvedConstraints.contains(StringTypeConstraint) -> StringTypeConstraint + resolvedConstraints.contains(RecursiveConstraint) -> RecursiveConstraint else -> NoTypeConstraint } } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt index 137152ae4..07f0d7bc6 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt @@ -2,12 +2,20 @@ package org.jetbrains.dukat.js.type.constraint.composite import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class UnionTypeConstraint( val types: List ) : ImmutableConstraint { override fun resolve(owner: PropertyOwner): Constraint { - return UnionTypeConstraint( types.map { it.resolve(owner) } ) + val resolvedTypes = types.map { it.resolve(owner) }.filter { it != RecursiveConstraint } + + return when (resolvedTypes.size) { + 0 -> NoTypeConstraint + 1 -> resolvedTypes[0] + else -> UnionTypeConstraint(resolvedTypes) + } } } \ No newline at end of file From ad4870274acf6378c41ca14c8f1c5a19c998084b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Nov 2019 13:05:45 +0100 Subject: [PATCH 076/172] Improve operator type analysis behaviour for comparisons --- compiler/test/data/javascript/conditional/if.d.kt | 2 +- compiler/test/data/javascript/object/modified.d.kt | 8 +++++++- compiler/test/data/javascript/object/modified.d.ts | 8 ++++++++ compiler/test/data/javascript/reference/recursive.d.kt | 4 +--- compiler/test/data/javascript/reference/recursive.d.ts | 3 ++- .../org/jetbrains/dukat/js/type/analysis/expression.kt | 9 +++++++-- 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/compiler/test/data/javascript/conditional/if.d.kt b/compiler/test/data/javascript/conditional/if.d.kt index 0cdcf086d..a8f815dda 100644 --- a/compiler/test/data/javascript/conditional/if.d.kt +++ b/compiler/test/data/javascript/conditional/if.d.kt @@ -15,7 +15,7 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun max(a: Any?, b: Any?): Any? +external fun max(a: Number, b: Number): Number external fun negate(a: Number): dynamic /* Number | Boolean */ diff --git a/compiler/test/data/javascript/object/modified.d.kt b/compiler/test/data/javascript/object/modified.d.kt index 5e7f24e02..63bd6ea47 100644 --- a/compiler/test/data/javascript/object/modified.d.kt +++ b/compiler/test/data/javascript/object/modified.d.kt @@ -34,4 +34,10 @@ external interface `T$1` { } } -external fun get3DVector(): `T$1` \ No newline at end of file +external fun get3DVector(): `T$1` + +external object obj { + var a: String +} + +external fun modObj() \ No newline at end of file diff --git a/compiler/test/data/javascript/object/modified.d.ts b/compiler/test/data/javascript/object/modified.d.ts index be83a5d40..baf0dce13 100644 --- a/compiler/test/data/javascript/object/modified.d.ts +++ b/compiler/test/data/javascript/object/modified.d.ts @@ -12,4 +12,12 @@ function get3DVector() { v2D.z = 1 return v2D +} + +var obj = { + a: "text" +} + +function modObj() { + obj.b = "text" } \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/recursive.d.kt b/compiler/test/data/javascript/reference/recursive.d.kt index a2f8c83df..3c6b5b2b3 100644 --- a/compiler/test/data/javascript/reference/recursive.d.kt +++ b/compiler/test/data/javascript/reference/recursive.d.kt @@ -15,6 +15,4 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun fibonacci(num: Any?): dynamic /* Number | Any? */ - -external fun fibonacci(num: Number): dynamic /* Number | Any? */ \ No newline at end of file +external fun fibonacci(num: Number): Number \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/recursive.d.ts b/compiler/test/data/javascript/reference/recursive.d.ts index 01933983c..47321f39a 100644 --- a/compiler/test/data/javascript/reference/recursive.d.ts +++ b/compiler/test/data/javascript/reference/recursive.d.ts @@ -3,5 +3,6 @@ function fibonacci(num) { if (num <= 1) return 1; - return fibonacci(num - 1) + fibonacci(num - 2); + //Using double minus here, to show that this is a number (for plus this isn't possible) + return fibonacci(num - 1) - -fibonacci(num - 2); } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 3ecc0e976..86a262577 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -46,7 +46,7 @@ fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: when (path.getNextDirection()) { PathWalker.Direction.First -> { left.calculateConstraints(owner, path) - //right isn't be evaluated + //right isn't being evaluated } PathWalker.Direction.Second -> { left.calculateConstraints(owner, path) @@ -64,11 +64,16 @@ fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: right.calculateConstraints(owner, path) NumberTypeConstraint } - "==", "===", "!=", "!==", ">", "<", ">=", "<=", "in", "instanceof" -> { + "==", "===", "!=", "!==", "in", "instanceof" -> { left.calculateConstraints(owner, path) right.calculateConstraints(owner, path) BooleanTypeConstraint } + ">", "<", ">=", "<=" -> { + left.calculateConstraints(owner, path) += NumberTypeConstraint + right.calculateConstraints(owner, path) += NumberTypeConstraint + BooleanTypeConstraint + } else -> { left.calculateConstraints(owner, path) right.calculateConstraints(owner, path) From ba100d4d825809d6ccdc48bf5b7122039f1c4bd8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Nov 2019 14:51:21 +0100 Subject: [PATCH 077/172] Add while statement --- typescript/ts-converter/src/AstConverter.ts | 21 +++++++++++++++++++ typescript/ts-converter/src/ast/AstFactory.ts | 10 +++++++++ .../ts-model-proto/src/Declarations.proto | 10 +++++++-- .../tsmodel/WhileStatementDeclaration.kt | 6 ++++++ .../dukat/tsmodel/factory/convertProtobuf.kt | 9 ++++++++ 5 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/WhileStatementDeclaration.kt diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index b7499da34..e22cca4fd 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -767,6 +767,21 @@ export class AstConverter { return interfaceDeclaration; } + convertIterationStatement(statement: ts.Node): Declaration | null { + let decl: Declaration | null = null; + + let body = this.convertTopLevelStatement(statement.statement); + + if (ts.isWhileStatement(statement)) { + decl = this.astFactory.createWhileStatement( + this.astExpressionConverter.convertExpression(statement.expression), + body + ) + } + + return decl + } + convertTopLevelStatement(statement: ts.Node): Array { let res: Array = []; @@ -809,6 +824,12 @@ export class AstConverter { this.convertTopLevelStatement(statement.thenStatement), elseStatement )) + } else if (ts.isIterationStatement(statement)) { + let iterationStatement = this.convertIterationStatement(statement); + + if (iterationStatement) { + res.push(iterationStatement) + } } else if (ts.isBlock(statement)) { let block = this.convertBlockStatement(statement); if (block) { diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index 564d3b700..6e40cc60d 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -144,6 +144,16 @@ export class AstFactory implements AstFactory { return topLevelEntity; } + createWhileStatement(condition: Expression, statement: Array): IfStatement { + let whileStatement = new declarations.WhileStatementDeclarationProto(); + whileStatement.setCondition(condition); + whileStatement.setStatementList(statement); + + let topLevelEntity = new declarations.TopLevelEntityProto(); + topLevelEntity.setWhilestatement(whileStatement); + return topLevelEntity; + } + createReturnStatement(expression: Expression | null): ReturnStatement { let returnStatement = new declarations.ReturnStatementDeclarationProto(); if (expression) { diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index b076ee179..deef5d7a7 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -270,6 +270,11 @@ message IfStatementDeclarationProto { repeated TopLevelEntityProto elseStatement = 3; } +message WhileStatementDeclarationProto { + ExpressionDeclarationProto condition = 1; + repeated TopLevelEntityProto statement = 2; +} + message ReturnStatementDeclarationProto { ExpressionDeclarationProto expression = 1; } @@ -342,8 +347,9 @@ message TopLevelEntityProto { ImportEqualsDeclarationProto importEquals = 9; ExpressionStatementDeclarationProto expressionStatement = 10; ReturnStatementDeclarationProto returnStatement = 11; - IfStatementDeclarationProto ifStatement = 12; - BlockDeclarationProto blockStatement = 13; + BlockDeclarationProto blockStatement = 12; + IfStatementDeclarationProto ifStatement = 13; + WhileStatementDeclarationProto whileStatement = 14; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/WhileStatementDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/WhileStatementDeclaration.kt new file mode 100644 index 000000000..3e3d2601a --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/WhileStatementDeclaration.kt @@ -0,0 +1,6 @@ +package org.jetbrains.dukat.tsmodel + +data class WhileStatementDeclaration( + val condition: ExpressionDeclaration, + val statement: TopLevelDeclaration +) : TopLevelDeclaration diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 1e8e2f41f..746e3e943 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -36,6 +36,7 @@ import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.TypeAliasDeclaration import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration +import org.jetbrains.dukat.tsmodel.WhileStatementDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.CallExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.ElementAccessExpressionDeclaration @@ -210,6 +211,13 @@ fun Declarations.IfStatementDeclarationProto.convert(): IfStatementDeclaration { ) } +fun Declarations.WhileStatementDeclarationProto.convert(): WhileStatementDeclaration { + return WhileStatementDeclaration( + condition = condition.convert(), + statement = statementList.convert() ?: BlockDeclaration(emptyList()) + ) +} + fun Declarations.ExpressionStatementDeclarationProto.convert(): ExpressionStatementDeclaration { return ExpressionStatementDeclaration(expression.convert()) } @@ -234,6 +242,7 @@ fun Declarations.TopLevelEntityProto.convert(): TopLevelDeclaration { hasExportAssignment() -> exportAssignment.convert() hasImportEquals() -> importEquals.convert() hasIfStatement() -> ifStatement.convert() + hasWhileStatement() -> whileStatement.convert() hasExpressionStatement() -> expressionStatement.convert() hasReturnStatement() -> returnStatement.convert() hasBlockStatement() -> blockStatement.convert() From c11923b27a92d84244eddedca599ee6ea52162af Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Nov 2019 15:39:56 +0100 Subject: [PATCH 078/172] Go through while loops once, and not at all (as alternative paths) --- .../data/javascript/conditional/while.d.kt | 18 ++++++++++++++++++ .../data/javascript/conditional/while.d.ts | 15 +++++++++++++++ .../dukat/js/type/analysis/introduceTypes.kt | 11 +++++++++++ 3 files changed, 44 insertions(+) create mode 100644 compiler/test/data/javascript/conditional/while.d.kt create mode 100644 compiler/test/data/javascript/conditional/while.d.ts diff --git a/compiler/test/data/javascript/conditional/while.d.kt b/compiler/test/data/javascript/conditional/while.d.kt new file mode 100644 index 000000000..5f4566c92 --- /dev/null +++ b/compiler/test/data/javascript/conditional/while.d.kt @@ -0,0 +1,18 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun product(arr: Any?): dynamic /* Number | Any? */ \ No newline at end of file diff --git a/compiler/test/data/javascript/conditional/while.d.ts b/compiler/test/data/javascript/conditional/while.d.ts new file mode 100644 index 000000000..b4b4304c0 --- /dev/null +++ b/compiler/test/data/javascript/conditional/while.d.ts @@ -0,0 +1,15 @@ + +function product(arr) { + let product + + let i = 0 + while (typeof arr[i++] == "number") { + if (product == undefined) { + product = 1 + } + + product *= arr[i - 1] + } + + return product +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index 0528ea91d..c3b0c33dc 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -29,6 +29,7 @@ import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration +import org.jetbrains.dukat.tsmodel.WhileStatementDeclaration fun FunctionDeclaration.addTo(owner: PropertyOwner) { if (this.body != null) { @@ -136,6 +137,15 @@ fun IfStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: Path } } +fun WhileStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { + condition.calculateConstraints(owner, path) += BooleanTypeConstraint + + return when (path.getNextDirection()) { + PathWalker.Direction.First -> statement.calculateConstraints(owner, path) + PathWalker.Direction.Second -> null + } +} + fun ExpressionStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) { expression.calculateConstraints(owner, path) } @@ -152,6 +162,7 @@ fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWal is ClassDeclaration -> this.addTo(owner, path) is VariableDeclaration -> this.addTo(owner, path) is IfStatementDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) + is WhileStatementDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) is ExpressionStatementDeclaration -> this.calculateConstraints(owner, path) is BlockDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) is ReturnStatementDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) From db1ee977ab7e38e8923a5c437ca4cfa6039eaf39 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Nov 2019 16:26:46 +0100 Subject: [PATCH 079/172] Add new expression --- .../ts-converter/src/ast/AstExpressionConverter.ts | 13 +++++++++++++ .../ts-converter/src/ast/AstExpressionFactory.ts | 10 ++++++++++ typescript/ts-model-proto/src/Declarations.proto | 8 +++++++- .../tsmodel/expression/NewExpressionDeclaration.kt | 8 ++++++++ .../dukat/tsmodel/factory/convertProtobuf.kt | 9 +++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/NewExpressionDeclaration.kt diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index 4b9b272b3..790dafd72 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -41,6 +41,10 @@ export class AstExpressionConverter { return AstExpressionFactory.createElementAccessExpressionDeclarationAsExpression(expression, argumentExpression); } + createNewExpression(expression: Expression, args: Array) { + return AstExpressionFactory.createNewExpressionDeclarationAsExpression(expression, args); + } + createNameExpression(name: NameEntity): Expression { return AstExpressionFactory.createNameExpressionDeclarationAsExpression(name) } @@ -125,6 +129,13 @@ export class AstExpressionConverter { ) } + convertNewExpression(expression: ts.NewExpression): Expression { + return this.createNewExpression( + this.convertExpression(expression.expression), + expression.arguments.map(arg => this.convertExpression(arg)) + ) + } + convertNameExpression(name: ts.EntityName): Expression { return this.createNameExpression( this.convertEntityName(name) @@ -265,6 +276,8 @@ export class AstExpressionConverter { return this.convertPropertyAccessExpression(expression) } else if (ts.isElementAccessExpression(expression)) { return this.convertElementAccessExpression(expression) + } else if (ts.isNewExpression(expression)) { + return this.convertNewExpression(expression) } else if (ts.isIdentifier(expression) || ts.isQualifiedName(expression)) { return this.convertNameExpression(expression); } else if (ts.isLiteralExpression(expression)) { diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index c9836a108..1bcbc4a37 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -69,6 +69,16 @@ export class AstExpressionFactory { return expressionProto; } + static createNewExpressionDeclarationAsExpression(expression: Expression, args: Array): Expression { + let newExpression = new declarations.NewExpressionDeclarationProto(); + newExpression.setExpression(expression); + newExpression.setArgumentsList(args); + + let expressionProto = new declarations.ExpressionDeclarationProto(); + expressionProto.setNewexpression(newExpression); + return expressionProto; + } + static createQualifierAsNameEntity(left: NameEntity, right: IdentifierEntity): NameEntity { let qualifier = new declarations.QualifierEntityProto(); qualifier.setLeft(left); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index deef5d7a7..22bdd2b8c 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -242,6 +242,11 @@ message ElementAccessExpressionDeclarationProto { ExpressionDeclarationProto argumentExpression = 2; } +message NewExpressionDeclarationProto { + ExpressionDeclarationProto expression = 1; + repeated ExpressionDeclarationProto arguments = 2; +} + message UnknownExpressionDeclarationProto { string meta = 1; } @@ -256,7 +261,8 @@ message ExpressionDeclarationProto { LiteralExpressionDeclarationProto literalExpression = 6; PropertyAccessExpressionDeclarationProto propertyAccessExpression = 7; ElementAccessExpressionDeclarationProto elementAccessExpression = 8; - UnknownExpressionDeclarationProto unknownExpression = 9; + NewExpressionDeclarationProto newExpression = 9; + UnknownExpressionDeclarationProto unknownExpression = 10; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/NewExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/NewExpressionDeclaration.kt new file mode 100644 index 000000000..9b446aed1 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/NewExpressionDeclaration.kt @@ -0,0 +1,8 @@ +package org.jetbrains.dukat.tsmodel.expression + +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +data class NewExpressionDeclaration( + val expression: ExpressionDeclaration, + val arguments: List +) : ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 746e3e943..b2fccb3d7 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -40,6 +40,7 @@ import org.jetbrains.dukat.tsmodel.WhileStatementDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.CallExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.ElementAccessExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.NewExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.TypeOfExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration @@ -448,6 +449,13 @@ fun Declarations.ElementAccessExpressionDeclarationProto.convert() : ElementAcce ) } +fun Declarations.NewExpressionDeclarationProto.convert(): NewExpressionDeclaration { + return NewExpressionDeclaration( + expression = expression.convert(), + arguments = argumentsList.map { it.convert() } + ) +} + fun Declarations.UnknownExpressionDeclarationProto.convert() : UnknownExpressionDeclaration { return UnknownExpressionDeclaration( meta = meta @@ -464,6 +472,7 @@ fun Declarations.ExpressionDeclarationProto.convert() : ExpressionDeclaration { hasLiteralExpression() -> literalExpression.convert() hasPropertyAccessExpression() -> propertyAccessExpression.convert() hasElementAccessExpression() -> elementAccessExpression.convert() + hasNewExpression() -> newExpression.convert() hasUnknownExpression() -> unknownExpression.convert() else -> throw Exception("unknown expression: ${this}") } From 6c2b4612bb0a5db0276b186bba8ae0ac26276c96 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Nov 2019 17:02:02 +0100 Subject: [PATCH 080/172] Remove 'propertyNames' property from 'PropertyOwner' interface --- .../js/type/constraint/properties/ClassConstraint.kt | 2 +- .../js/type/constraint/properties/ObjectConstraint.kt | 2 +- .../reference/PropertyOwnerReferenceConstraint.kt | 5 +---- .../dukat/js/type/export_resolution/ExportResolver.kt | 4 ++-- .../js/type/export_resolution/GeneralExportResolver.kt | 10 +++++----- .../dukat/js/type/property_owner/PropertyOwner.kt | 2 -- .../jetbrains/dukat/js/type/property_owner/Scope.kt | 2 +- 7 files changed, 11 insertions(+), 16 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt index dabb7ba03..403dd8053 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt @@ -4,7 +4,7 @@ import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class ClassConstraint(val prototype: ObjectConstraint = ObjectConstraint()) : PropertyOwnerConstraint { - override val propertyNames: Set + val propertyNames: Set get() = staticMembers.keys private val staticMembers = LinkedHashMap() diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt index 04354fe41..5ab5c4dc4 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt @@ -7,7 +7,7 @@ import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaratio class ObjectConstraint( private val instantiatedClass: ClassConstraint? = null ) : PropertyOwnerConstraint { - override val propertyNames: Set + val propertyNames: Set get() { val names = mutableSetOf() names.addAll(properties.keys) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt index 03227ef9a..d6da0e118 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt @@ -7,10 +7,7 @@ import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.panic.raiseConcern abstract class PropertyOwnerReferenceConstraint : PropertyOwnerConstraint { - override val propertyNames: Set - get() = raiseConcern("Properties of a reference should never be listed.") { emptySet() } - - protected val modifiedProperties = LinkedHashMap() + private val modifiedProperties = LinkedHashMap() override fun set(name: String, data: Constraint) { modifiedProperties[name] = data diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt index 14c2c1995..4063cd269 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt @@ -1,8 +1,8 @@ package org.jetbrains.dukat.js.type.export_resolution -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.property_owner.Scope import org.jetbrains.dukat.tsmodel.TopLevelDeclaration interface ExportResolver { - fun resolve(owner: PropertyOwner) : List + fun resolve(scope: Scope) : List } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt index 8d5c6d31b..7a26369fa 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt @@ -1,14 +1,14 @@ package org.jetbrains.dukat.js.type.export_resolution -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.js.type.constraint.resolution.toDeclaration +import org.jetbrains.dukat.js.type.property_owner.Scope import org.jetbrains.dukat.tsmodel.TopLevelDeclaration class GeneralExportResolver : ExportResolver { - override fun resolve(owner: PropertyOwner) : List { - return owner.propertyNames.mapNotNull { propertyName -> - val resolvedConstraint = owner[propertyName]?.resolve(owner) - resolvedConstraint?.toDeclaration(propertyName) + override fun resolve(scope: Scope) : List { + return scope.propertyNames.mapNotNull { propertyName -> + val resolvedConstraint = scope[propertyName].resolve(scope) + resolvedConstraint.toDeclaration(propertyName) } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt index dec881b10..500fccfdc 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt @@ -10,8 +10,6 @@ import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaratio import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration interface PropertyOwner { - val propertyNames: Set - operator fun set(name: String, data: Constraint) operator fun set(identifier: IdentifierEntity, data: Constraint) { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt index 92d155b64..84ade79ba 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt @@ -5,7 +5,7 @@ import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.reference.ReferenceConstraint class Scope : PropertyOwner { - override val propertyNames: Set + val propertyNames: Set get() = properties.keys private val properties = LinkedHashMap() From f6d2eb8f8a75bfda448fac20ac5bcf8c8d725c9b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Nov 2019 10:42:00 +0100 Subject: [PATCH 081/172] Track object instantiation --- .../data/javascript/instance/instance.d.kt | 26 ++++++++++ .../data/javascript/instance/instance.d.ts | 10 ++++ .../dukat/js/type/analysis/expression.kt | 14 ++++++ .../dukat/js/type/analysis/introduceTypes.kt | 12 ++++- .../constraint/properties/ClassConstraint.kt | 8 +++- .../constraint/properties/ObjectConstraint.kt | 39 ++++++++++----- .../resolution/constraintToDeclaration.kt | 47 +++++++++++++++---- 7 files changed, 132 insertions(+), 24 deletions(-) create mode 100644 compiler/test/data/javascript/instance/instance.d.kt create mode 100644 compiler/test/data/javascript/instance/instance.d.ts diff --git a/compiler/test/data/javascript/instance/instance.d.kt b/compiler/test/data/javascript/instance/instance.d.kt new file mode 100644 index 000000000..e38603e9c --- /dev/null +++ b/compiler/test/data/javascript/instance/instance.d.kt @@ -0,0 +1,26 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external open class C { + open fun foo(): String +} + +external object o { + fun foo(): String +} + +external var str: String \ No newline at end of file diff --git a/compiler/test/data/javascript/instance/instance.d.ts b/compiler/test/data/javascript/instance/instance.d.ts new file mode 100644 index 000000000..826a0ab90 --- /dev/null +++ b/compiler/test/data/javascript/instance/instance.d.ts @@ -0,0 +1,10 @@ + +class C { + foo() { + return "text" + } +} + +var o = new C() + +var str = o.foo() \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 86a262577..06c29a305 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -9,6 +9,7 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeCons import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint import org.jetbrains.dukat.js.type.constraint.reference.call.CallArgumentConstraint import org.jetbrains.dukat.js.type.constraint.reference.call.CallResultConstraint import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint @@ -16,6 +17,7 @@ import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.CallExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.NewExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.TypeOfExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration @@ -125,6 +127,17 @@ fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: P ) } +fun NewExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { + val classConstraints = expression.calculateConstraints(owner, path) + + //TODO add constraints for constructor call + arguments.map { it.calculateConstraints(owner, path) } + + return ObjectConstraint( + instantiatedClass = classConstraints as ClassConstraint + ) +} + fun ObjectLiteralExpressionDeclaration.calculateConstraints(path: PathWalker) : ObjectConstraint { val obj = ObjectConstraint() members.forEach { it.addTo(obj, path) } @@ -150,6 +163,7 @@ fun ExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathW is UnaryExpressionDeclaration -> this.calculateConstraints(owner, path) is TypeOfExpressionDeclaration -> this.calculateConstraints(owner, path) is CallExpressionDeclaration -> this.calculateConstraints(owner, path) + is NewExpressionDeclaration -> this.calculateConstraints(owner, path) is LiteralExpressionDeclaration -> this.calculateConstraints(path) else -> CompositeConstraint(NoTypeConstraint) } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index c3b0c33dc..95c678379 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -101,7 +101,17 @@ fun MemberDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { fun MemberDeclaration.addToClass(owner: ClassConstraint, path: PathWalker) { when (this) { - is FunctionDeclaration -> if (this.modifiers.contains(ModifierDeclaration.STATIC_KEYWORD)) { this.addTo(owner) } else { this.addTo(owner.prototype) } + is FunctionDeclaration -> if (this.modifiers.contains(ModifierDeclaration.STATIC_KEYWORD)) { + this.addTo(owner) + } else { + val ownerPrototype = owner["prototype"] + + if (ownerPrototype is PropertyOwner) { + this.addTo(ownerPrototype) + } else { + raiseConcern("Class prototype corrupt! Cannot add members.") { } + } + } is PropertyDeclaration -> this.addTo(owner, path) else -> raiseConcern("Unexpected member entity type <${this::class}>") { this } } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt index 403dd8053..c0851c369 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt @@ -3,12 +3,16 @@ package org.jetbrains.dukat.js.type.constraint.properties import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -class ClassConstraint(val prototype: ObjectConstraint = ObjectConstraint()) : PropertyOwnerConstraint { +class ClassConstraint(prototype: ObjectConstraint = ObjectConstraint()) : PropertyOwnerConstraint { val propertyNames: Set get() = staticMembers.keys private val staticMembers = LinkedHashMap() + init { + this["prototype"] = prototype + } + override fun set(name: String, data: Constraint) { staticMembers[name] = data } @@ -18,7 +22,7 @@ class ClassConstraint(val prototype: ObjectConstraint = ObjectConstraint()) : Pr } override fun resolve(owner: PropertyOwner): ClassConstraint { - val resolvedConstraint = ClassConstraint(prototype = prototype.resolve(owner)) + val resolvedConstraint = ClassConstraint() propertyNames.forEach { resolvedConstraint[it] = this[it]!!.resolve(owner) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt index 5ab5c4dc4..83d352705 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt @@ -2,20 +2,13 @@ package org.jetbrains.dukat.js.type.constraint.properties import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaration +import org.jetbrains.dukat.panic.raiseConcern class ObjectConstraint( - private val instantiatedClass: ClassConstraint? = null + val instantiatedClass: PropertyOwnerConstraint? = null ) : PropertyOwnerConstraint { val propertyNames: Set - get() { - val names = mutableSetOf() - names.addAll(properties.keys) - instantiatedClass?.let { - names.addAll(it.prototype.propertyNames) - } - return names - } + get() = properties.keys private val properties = LinkedHashMap() @@ -26,12 +19,34 @@ class ObjectConstraint( override fun get(name: String): Constraint? { return when { properties.containsKey(name) -> properties[name] - else -> instantiatedClass?.prototype?.get(name) + else -> { + if(instantiatedClass != null) { + val classPrototype = instantiatedClass["prototype"] + + if (classPrototype is PropertyOwner) { + classPrototype[name] + } else { + raiseConcern("Instantiating constraint which cannot be instantiated!") { null } + } + } else { + null + } + } } } override fun resolve(owner: PropertyOwner): ObjectConstraint { - val resolvedConstraint = ObjectConstraint() + val resolvedConstraint = if (instantiatedClass == null) { + ObjectConstraint() + } else { + val resolvedClass = instantiatedClass.resolve(owner) + + if (resolvedClass is PropertyOwnerConstraint) { + ObjectConstraint(resolvedClass) + } else { + raiseConcern("Instantiating constraint which cannot be instantiated!") { ObjectConstraint() } + } + } propertyNames.forEach { resolvedConstraint[it] = this[it]!!.resolve(owner) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index 3e7fab69c..c6e81501e 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -12,6 +12,7 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstra import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.js.type.type.anyNullableType import org.jetbrains.dukat.js.type.type.booleanType import org.jetbrains.dukat.js.type.type.numberType @@ -87,15 +88,26 @@ fun Constraint.toMemberDeclaration(name: String, isStatic: Boolean = false) : Me fun ClassConstraint.toDeclaration(name: String) : ClassDeclaration { val members = mutableListOf() - members.addAll( - prototype.propertyNames.mapNotNull { memberName -> - prototype[memberName]?.toMemberDeclaration(name = memberName, isStatic = false) - } - ) + val prototype = this["prototype"] + + if (prototype is ObjectConstraint) { + members.addAll( + prototype.propertyNames.mapNotNull { memberName -> + prototype[memberName]?.toMemberDeclaration(name = memberName, isStatic = false) + } + ) + } else { + raiseConcern("Class prototype is no object. Conversion might be erroneous!") { } + } members.addAll( propertyNames.mapNotNull { memberName -> - this[memberName]?.toMemberDeclaration(name = memberName, isStatic = true) + //Don't output the prototype object + if (memberName != "prototype") { + this[memberName]?.toMemberDeclaration(name = memberName, isStatic = true) + } else { + null + } } ) @@ -122,11 +134,28 @@ fun UnionTypeConstraint.toType() : UnionTypeDeclaration { ) } +fun ObjectConstraint.mapMembers() : List { + val members = mutableListOf() + + members.addAll( + propertyNames.mapNotNull { memberName -> + this[memberName]?.toMemberDeclaration(name = memberName) + } + ) + + if (instantiatedClass is PropertyOwner) { + val classPrototype = instantiatedClass["prototype"] + + if (classPrototype is ObjectConstraint) + members.addAll(classPrototype.mapMembers()) + } + + return members +} + fun ObjectConstraint.toType() : ObjectLiteralDeclaration { return ObjectLiteralDeclaration( - members = propertyNames.mapNotNull { memberName -> - this[memberName]?.toMemberDeclaration(name = memberName) - }, + members = mapMembers(), nullable = true ) } From 79b1286f01568ba14aacde50f4338fcbad33e3cd Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Nov 2019 14:26:05 +0100 Subject: [PATCH 082/172] Refractor declaration proto --- .../src/ast/AstExpressionFactory.ts | 20 +-- typescript/ts-converter/src/ast/AstFactory.ts | 126 +++++++------- typescript/ts-converter/src/converter.ts | 2 +- .../ts-model-proto/src/Declarations.proto | 154 +++++++++-------- .../dukat/tsmodel/factory/convertProtobuf.kt | 161 ++++++++++++------ .../JsRuntimeByteArrayTranslator.kt | 4 +- .../ts/translator/JsRuntimeFileTranslator.kt | 4 +- 7 files changed, 260 insertions(+), 211 deletions(-) diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index 1bcbc4a37..4e8467548 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -80,25 +80,25 @@ export class AstExpressionFactory { } static createQualifierAsNameEntity(left: NameEntity, right: IdentifierEntity): NameEntity { - let qualifier = new declarations.QualifierEntityProto(); + let qualifier = new declarations.QualifierDeclarationProto(); qualifier.setLeft(left); qualifier.setRight(right); - let nameEntity = new declarations.NameEntityProto(); - nameEntity.setQualifier(qualifier); - return nameEntity; + let name = new declarations.NameDeclarationProto(); + name.setQualifier(qualifier); + return name; } static createIdentifier(value: string): IdentifierEntity { - let identifierProto = new declarations.IdentifierEntityProto(); - identifierProto.setValue(value); - return identifierProto; + let identifier = new declarations.IdentifierDeclarationProto(); + identifier.setValue(value); + return identifier; } static createIdentifierAsNameEntity(value: string): NameEntity { - let nameEntity = new declarations.NameEntityProto(); - nameEntity.setIdentifier(this.createIdentifier(value)); - return nameEntity; + let name = new declarations.NameDeclarationProto(); + name.setIdentifier(this.createIdentifier(value)); + return name; } static createNameExpressionDeclarationAsExpression(name: NameEntity): Expression { diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index 6e40cc60d..2d48eae49 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -58,7 +58,7 @@ export class AstFactory implements AstFactory { callSignature.setType(type); callSignature.setTypeparametersList(typeParams); - let memberProto = new declarations.MemberEntityProto(); + let memberProto = new declarations.MemberDeclarationProto(); memberProto.setCallsignature(callSignature); return memberProto; } @@ -72,9 +72,9 @@ export class AstFactory implements AstFactory { classDeclaration.setTypeparametersList(typeParams); classDeclaration.setParententitiesList(parentEntities); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setClassdeclaration(classDeclaration); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setClassdeclaration(classDeclaration); + return topLevelDeclaration; } createConstructorDeclaration(parameters: Array, typeParams: Array, modifiers: Array): ConstructorDeclaration { @@ -84,7 +84,7 @@ export class AstFactory implements AstFactory { constuctorDeclaration.setTypeparametersList(typeParams); constuctorDeclaration.setModifiersList(modifiers); - let memberProto = new declarations.MemberEntityProto(); + let memberProto = new declarations.MemberDeclarationProto(); memberProto.setConstructordeclaration(constuctorDeclaration); return memberProto; } @@ -96,17 +96,17 @@ export class AstFactory implements AstFactory { } createEnumDeclaration(name: string, values: Array): EnumDeclaration { - let enumDeclaration = new declarations.EnumDeclaration(); + let enumDeclaration = new declarations.EnumDeclarationProto(); enumDeclaration.setName(name); enumDeclaration.setValuesList(values); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setEnumdeclaration(enumDeclaration); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setEnumdeclaration(enumDeclaration); + return topLevelDeclaration; } createEnumTokenDeclaration(value: string, meta: string): EnumTokenDeclaration { - let enumToken = new declarations.EnumTokenDeclaration(); + let enumToken = new declarations.EnumTokenDeclarationProto(); enumToken.setValue(value); enumToken.setMeta(meta); return enumToken; @@ -117,18 +117,18 @@ export class AstFactory implements AstFactory { exportAssignment.setName(name); exportAssignment.setIsexportequals(isExportEquals); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setExportassignment(exportAssignment); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setExportassignment(exportAssignment); + return topLevelDeclaration; } createExpressionStatement(expression: Expression): ExpressionStatement { let expressionStatement = new declarations.ExpressionStatementDeclarationProto(); expressionStatement.setExpression(expression); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setExpressionstatement(expressionStatement); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setExpressionstatement(expressionStatement); + return topLevelDeclaration; } createIfStatement(condition: Expression, thenStatement: Array, elseStatement: Array | null): IfStatement { @@ -139,9 +139,9 @@ export class AstFactory implements AstFactory { ifStatement.setElsestatementList(elseStatement); } - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setIfstatement(ifStatement); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setIfstatement(ifStatement); + return topLevelDeclaration; } createWhileStatement(condition: Expression, statement: Array): IfStatement { @@ -149,9 +149,9 @@ export class AstFactory implements AstFactory { whileStatement.setCondition(condition); whileStatement.setStatementList(statement); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setWhilestatement(whileStatement); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setWhilestatement(whileStatement); + return topLevelDeclaration; } createReturnStatement(expression: Expression | null): ReturnStatement { @@ -160,9 +160,9 @@ export class AstFactory implements AstFactory { returnStatement.setExpression(expression); } - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setReturnstatement(returnStatement); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setReturnstatement(returnStatement); + return topLevelDeclaration; } createBlockDeclaration(statements: Array): Block { @@ -174,9 +174,9 @@ export class AstFactory implements AstFactory { createBlockStatementDeclaration(statements: Array): Block { let block = this.createBlockDeclaration(statements); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setBlockstatement(block); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setBlockstatement(block); + return topLevelDeclaration; } private createFunctionDeclaration(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, body: Block | null, uid: String): ProtoMessage { @@ -196,7 +196,7 @@ export class AstFactory implements AstFactory { createFunctionDeclarationAsMember(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, body: Block | null, uid: String): FunctionDeclaration { let functionDeclaration = this.createFunctionDeclaration(name, parameters, type, typeParams, modifiers, body, uid); - let memberProto = new declarations.MemberEntityProto(); + let memberProto = new declarations.MemberDeclarationProto(); memberProto.setFunctiondeclaration(functionDeclaration); return memberProto; } @@ -204,9 +204,9 @@ export class AstFactory implements AstFactory { createFunctionDeclarationAsTopLevel(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, body: Block | null, uid: String): FunctionDeclaration { let functionDeclaration = this.createFunctionDeclaration(name, parameters, type, typeParams, modifiers, body, uid); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setFunctiondeclaration(functionDeclaration); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setFunctiondeclaration(functionDeclaration); + return topLevelDeclaration; } createFunctionTypeDeclaration(parameters: Array, type: ParameterValue): FunctionTypeDeclaration { @@ -234,15 +234,15 @@ export class AstFactory implements AstFactory { } createIdentifierDeclarationAsNameEntity(value: string): IdentifierEntity { - let identifierProto = new declarations.IdentifierEntityProto(); + let identifierProto = new declarations.IdentifierDeclarationProto(); identifierProto.setValue(value); - let nameEntity = new declarations.NameEntityProto(); - nameEntity.setIdentifier(identifierProto); - return nameEntity; + let nameDeclaration = new declarations.NameDeclarationProto(); + nameDeclaration.setIdentifier(identifierProto); + return nameDeclaration; } createIdentifierDeclaration(value: string): IdentifierEntity { - let identifierProto = new declarations.IdentifierEntityProto(); + let identifierProto = new declarations.IdentifierDeclarationProto(); identifierProto.setValue(value); return identifierProto; } @@ -253,9 +253,9 @@ export class AstFactory implements AstFactory { importEqualsDeclaration.setModulereference(moduleReference); importEqualsDeclaration.setUid(uid); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setImportequals(importEqualsDeclaration); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setImportequals(importEqualsDeclaration); + return topLevelDeclaration; } createIndexSignatureDeclaration(indexTypes: Array, returnType: ParameterValue): IndexSignatureDeclaration { @@ -263,9 +263,9 @@ export class AstFactory implements AstFactory { indexSignatureDeclaration.setIndextypesList(indexTypes); indexSignatureDeclaration.setReturntype(returnType); - let memberEntity = new declarations.MemberEntityProto(); - memberEntity.setIndexsignature(indexSignatureDeclaration); - return memberEntity; + let memberDeclaration = new declarations.MemberDeclarationProto(); + memberDeclaration.setIndexsignature(indexSignatureDeclaration); + return memberDeclaration; } createInterfaceDeclaration(name: NameEntity, members: Array, typeParams: Array, parentEntities: Array, definitionsInfo: Array, uid: String): InterfaceDeclaration { @@ -277,9 +277,9 @@ export class AstFactory implements AstFactory { interfaceDeclaration.setTypeparametersList(typeParams); interfaceDeclaration.setParententitiesList(parentEntities); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setInterfacedeclaration(interfaceDeclaration); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setInterfacedeclaration(interfaceDeclaration); + return topLevelDeclaration; } createIntersectionTypeDeclaration(params: Array): IntersectionTypeDeclaration { @@ -298,7 +298,7 @@ export class AstFactory implements AstFactory { methodDeclaration.setType(type); methodDeclaration.setTypeparamsList(typeParams); - let memberProto = new declarations.MemberEntityProto(); + let memberProto = new declarations.MemberDeclarationProto(); memberProto.setFunctionDeclarataion(memberProto); return memberProto; } @@ -312,7 +312,7 @@ export class AstFactory implements AstFactory { methodSignature.setOptional(optional); methodSignature.setModifiersList(modifiers); - let memberProto = new declarations.MemberEntityProto(); + let memberProto = new declarations.MemberDeclarationProto(); memberProto.setMethodsignature(methodSignature); return memberProto; } @@ -338,9 +338,9 @@ export class AstFactory implements AstFactory { createModuleDeclarationAsTopLevel(packageName: NameEntity, toplevels: Declaration[], modifiers: Array, definitionsInfo: Array, uid: string, resourceName: string, root: boolean): ModuleDeclaration { let module = this.createModuleDeclaration(packageName, toplevels, modifiers, definitionsInfo, uid, resourceName, root); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setModuledeclaration(module); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setModuledeclaration(module); + return topLevelDeclaration; } createObjectLiteral(members: Array): ObjectLiteral { @@ -365,17 +365,17 @@ export class AstFactory implements AstFactory { } createQualifiedNameDeclaration(left: NameEntity, right: IdentifierEntity): QualifierEntity { - let qualifier = new declarations.QualifierEntityProto(); + let qualifier = new declarations.QualifierDeclarationProto(); qualifier.setLeft(left); qualifier.setRight(right); - let nameEntity = new declarations.NameEntityProto(); - nameEntity.setQualifier(qualifier); - return nameEntity; + let nameDeclaration = new declarations.NameDeclarationProto(); + nameDeclaration.setQualifier(qualifier); + return nameDeclaration; } createReferenceEntity(uid: string): ReferenceEntity { - let reference = new declarations.ReferenceEntityProto(); + let reference = new declarations.ReferenceDeclarationProto(); reference.setUid(uid); return reference; } @@ -426,9 +426,9 @@ export class AstFactory implements AstFactory { typeAlias.setTypereference(typeReference); typeAlias.setUid(uid); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setAliasdeclaration(typeAlias); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setAliasdeclaration(typeAlias); + return topLevelDeclaration; } createTypeReferenceDeclaration(value: NameEntity, params: Array, typeReference: ReferenceEntity | null = null): TypeDeclaration { @@ -489,7 +489,7 @@ export class AstFactory implements AstFactory { propertyDeclaration.setOptional(optional); propertyDeclaration.setModifiersList(modifiers); - let memberProto = new declarations.MemberEntityProto(); + let memberProto = new declarations.MemberDeclarationProto(); memberProto.setProperty(propertyDeclaration); return memberProto; } @@ -504,9 +504,9 @@ export class AstFactory implements AstFactory { } variableDeclaration.setUid(uid); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setVariabledeclaration(variableDeclaration); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setVariabledeclaration(variableDeclaration); + return topLevelDeclaration; } } \ No newline at end of file diff --git a/typescript/ts-converter/src/converter.ts b/typescript/ts-converter/src/converter.ts index a50a629a9..9bce792a4 100644 --- a/typescript/ts-converter/src/converter.ts +++ b/typescript/ts-converter/src/converter.ts @@ -74,7 +74,7 @@ export function translate(stdlib: string, packageName: string, files: Array>(); let sourceSets = files.map(fileName => createSourceSet(fileName, stdlib, packageName, libDeclarations)); - let sourceSetBundle = new declarations.SourceSetBundleProto(); + let sourceSetBundle = new declarations.SourceBundleDeclarationProto(); let astFactory = createAstFactory(); let libRootUid = ""; diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 22bdd2b8c..7ee9e2124 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -1,20 +1,26 @@ syntax = "proto3"; -package dukat.ast.proto; +package org.jetbrains.dukat.tsmodelproto; -option java_outer_classname = "Declarations"; +option java_multiple_files = true; -message DefinitionInfoDeclarationProto { - string fileName = 1; +message NameDeclarationProto { + oneof type { + IdentifierDeclarationProto identifier = 1; + QualifierDeclarationProto qualifier = 2; + } } -message EnumTokenDeclaration { +message IdentifierDeclarationProto { string value = 1; - string meta = 2; } -message EnumDeclaration { - string name = 1; - repeated EnumTokenDeclaration values = 2; +message QualifierDeclarationProto { + NameDeclarationProto left = 1; + IdentifierDeclarationProto right = 3; +} + +message DefinitionInfoDeclarationProto { + string fileName = 1; } message ExportAssignmentDeclarationProto { @@ -22,23 +28,6 @@ message ExportAssignmentDeclarationProto { bool isExportEquals = 2; } -message NameEntityProto { - oneof type { - IdentifierEntityProto identifier = 1; - QualifierEntityProto qualifier = 2; - } -} - -message IdentifierEntityProto { - string value = 1; -} - -message QualifierEntityProto { - NameEntityProto left = 1; - IdentifierEntityProto right = 3; -} - - message ParameterValueDeclarationProto { oneof type { StringLiteralDeclarationProto stringLiteral = 1; @@ -62,7 +51,7 @@ message ThisTypeDeclarationProto { message ImportEqualsDeclarationProto { string name = 1; - NameEntityProto moduleReference = 2; + NameDeclarationProto moduleReference = 2; string uid = 3; } @@ -72,7 +61,7 @@ message FunctionTypeDeclarationProto { } message TypeParameterDeclarationProto { - NameEntityProto name = 1; + NameDeclarationProto name = 1; repeated ParameterValueDeclarationProto constraints = 2; ParameterValueDeclarationProto defaultValue = 3; } @@ -90,13 +79,13 @@ message UnionTypeDeclarationProto { } message TypeReferenceDeclarationProto { - NameEntityProto value = 1; + NameDeclarationProto value = 1; repeated ParameterValueDeclarationProto params = 2; - ReferenceEntityProto typeReference = 3; + ReferenceDeclarationProto typeReference = 3; } message TypeParamReferenceDeclarationProto { - NameEntityProto value = 1; + NameDeclarationProto value = 1; } message CallSignatureDeclarationProto { @@ -112,7 +101,7 @@ message ConstructorDeclarationProto { } message BlockDeclarationProto { - repeated TopLevelEntityProto statements = 1; + repeated TopLevelDeclarationProto statements = 1; } message FunctionDeclarationProto { @@ -153,10 +142,10 @@ message ModifierDeclarationProto { } message ObjectLiteralDeclarationProto { - repeated MemberEntityProto members = 1; + repeated MemberDeclarationProto members = 1; } -message MemberEntityProto { +message MemberDeclarationProto { oneof type { CallSignatureDeclarationProto callSignature = 1; ConstructorDeclarationProto constructorDeclaration = 2; @@ -168,7 +157,7 @@ message MemberEntityProto { } } -message ReferenceEntityProto { +message ReferenceDeclarationProto { string uid = 1; } @@ -189,7 +178,7 @@ message BigIntLiteralExpressionDeclarationProto { } message ObjectLiteralExpressionDeclarationProto { - repeated MemberEntityProto members = 1; + repeated MemberDeclarationProto members = 1; } message RegExLiteralExpressionDeclarationProto { @@ -208,7 +197,7 @@ message LiteralExpressionDeclarationProto { } message NameExpressionDeclarationProto { - NameEntityProto name = 1; + NameDeclarationProto name = 1; } message BinaryExpressionDeclarationProto { @@ -234,7 +223,7 @@ message CallExpressionDeclarationProto { message PropertyAccessExpressionDeclarationProto { ExpressionDeclarationProto expression = 1; - IdentifierEntityProto name = 2; + IdentifierDeclarationProto name = 2; } message ElementAccessExpressionDeclarationProto { @@ -272,13 +261,13 @@ message ExpressionStatementDeclarationProto { message IfStatementDeclarationProto { ExpressionDeclarationProto condition = 1; - repeated TopLevelEntityProto thenStatement = 2; - repeated TopLevelEntityProto elseStatement = 3; + repeated TopLevelDeclarationProto thenStatement = 2; + repeated TopLevelDeclarationProto elseStatement = 3; } message WhileStatementDeclarationProto { ExpressionDeclarationProto condition = 1; - repeated TopLevelEntityProto statement = 2; + repeated TopLevelDeclarationProto statement = 2; } message ReturnStatementDeclarationProto { @@ -302,52 +291,55 @@ message VariableDeclarationProto { } message TypeAliasDeclarationProto { - NameEntityProto aliasName = 1; - repeated IdentifierEntityProto typeParameters = 2; + NameDeclarationProto aliasName = 1; + repeated IdentifierDeclarationProto typeParameters = 2; ParameterValueDeclarationProto typeReference = 3; string uid = 4; } message HeritageClauseDeclarationProto { - NameEntityProto name = 1; + NameDeclarationProto name = 1; repeated ParameterValueDeclarationProto typeArguments = 2; bool extending = 3; - ReferenceEntityProto typeReference = 4; + ReferenceDeclarationProto typeReference = 4; } -message SourceFileDeclarationProto { - string fileName = 1; - ModuleDeclarationProto root = 2; - repeated IdentifierEntityProto referencedFiles = 3; +message EnumTokenDeclarationProto { + string value = 1; + string meta = 2; } -message SourceSetDeclarationProto { - string sourceName = 1; - repeated SourceFileDeclarationProto sources = 2; +message EnumDeclarationProto { + string name = 1; + repeated EnumTokenDeclarationProto values = 2; } -message SourceSetBundleProto { - repeated SourceSetDeclarationProto sources = 1; +message ClassDeclarationProto { + NameDeclarationProto name = 1; + repeated MemberDeclarationProto members = 2; + repeated TypeParameterDeclarationProto typeParameters = 3; + repeated HeritageClauseDeclarationProto parentEntities = 4; + repeated ModifierDeclarationProto modifiers = 5; + string uid = 6; } -message ModuleDeclarationProto { - NameEntityProto packageName = 1; - repeated TopLevelEntityProto declarations = 2; - repeated ModifierDeclarationProto modifiers = 3; - repeated DefinitionInfoDeclarationProto definitionsInfo = 4; - string uid = 5; - string resourceName = 6; - bool root = 7; +message InterfaceDeclarationProto { + NameDeclarationProto name = 1; + repeated MemberDeclarationProto members = 2; + repeated TypeParameterDeclarationProto typeParameters = 3; + repeated HeritageClauseDeclarationProto parentEntities = 4; + repeated DefinitionInfoDeclarationProto definitionsInfo = 5; + string uid = 6; } -message TopLevelEntityProto { +message TopLevelDeclarationProto { oneof type { ClassDeclarationProto classDeclaration = 1; InterfaceDeclarationProto interfaceDeclaration = 2; VariableDeclarationProto variableDeclaration = 3; FunctionDeclarationProto functionDeclaration = 4; TypeAliasDeclarationProto aliasDeclaration = 5; - EnumDeclaration enumDeclaration = 6; + EnumDeclarationProto enumDeclaration = 6; ModuleDeclarationProto moduleDeclaration = 7; ExportAssignmentDeclarationProto exportAssignment = 8; ImportEqualsDeclarationProto importEquals = 9; @@ -359,21 +351,27 @@ message TopLevelEntityProto { } } -message ClassDeclarationProto { - NameEntityProto name = 1; - repeated MemberEntityProto members = 2; - repeated TypeParameterDeclarationProto typeParameters = 3; - repeated HeritageClauseDeclarationProto parentEntities = 4; - repeated ModifierDeclarationProto modifiers = 5; - string uid = 6; +message ModuleDeclarationProto { + NameDeclarationProto packageName = 1; + repeated TopLevelDeclarationProto declarations = 2; + repeated ModifierDeclarationProto modifiers = 3; + repeated DefinitionInfoDeclarationProto definitionsInfo = 4; + string uid = 5; + string resourceName = 6; + bool root = 7; } +message SourceFileDeclarationProto { + string fileName = 1; + ModuleDeclarationProto root = 2; + repeated IdentifierDeclarationProto referencedFiles = 3; +} -message InterfaceDeclarationProto { - NameEntityProto name = 1; - repeated MemberEntityProto members = 2; - repeated TypeParameterDeclarationProto typeParameters = 3; - repeated HeritageClauseDeclarationProto parentEntities = 4; - repeated DefinitionInfoDeclarationProto definitionsInfo = 5; - string uid = 6; +message SourceSetDeclarationProto { + string sourceName = 1; + repeated SourceFileDeclarationProto sources = 2; +} + +message SourceBundleDeclarationProto { + repeated SourceSetDeclarationProto sources = 1; } \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index b2fccb3d7..48f11a3fb 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -1,6 +1,5 @@ package org.jetbrains.dukat.tsmodel.factory -import dukat.ast.proto.Declarations import org.jetbrains.dukat.astCommon.Entity import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.astCommon.NameEntity @@ -65,8 +64,60 @@ import org.jetbrains.dukat.tsmodel.types.TupleDeclaration import org.jetbrains.dukat.tsmodel.types.TypeDeclaration import org.jetbrains.dukat.tsmodel.types.TypeParamReferenceDeclaration import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration - -fun Declarations.NameEntityProto.convert(): NameEntity { +import org.jetbrains.dukat.tsmodelproto.BigIntLiteralExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.BinaryExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.BlockDeclarationProto +import org.jetbrains.dukat.tsmodelproto.BooleanLiteralExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.CallExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.CallSignatureDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ClassDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ConstructorDeclarationProto +import org.jetbrains.dukat.tsmodelproto.DefinitionInfoDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ElementAccessExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.EnumDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ExportAssignmentDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ExpressionStatementDeclarationProto +import org.jetbrains.dukat.tsmodelproto.FunctionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.HeritageClauseDeclarationProto +import org.jetbrains.dukat.tsmodelproto.IdentifierDeclarationProto +import org.jetbrains.dukat.tsmodelproto.IfStatementDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ImportEqualsDeclarationProto +import org.jetbrains.dukat.tsmodelproto.IndexSignatureDeclarationProto +import org.jetbrains.dukat.tsmodelproto.InterfaceDeclarationProto +import org.jetbrains.dukat.tsmodelproto.LiteralExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.MemberDeclarationProto +import org.jetbrains.dukat.tsmodelproto.MethodSignatureDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ModifierDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ModuleDeclarationProto +import org.jetbrains.dukat.tsmodelproto.NameDeclarationProto +import org.jetbrains.dukat.tsmodelproto.NameExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.NewExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.NumericLiteralExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ObjectLiteralExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ParameterDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ParameterValueDeclarationProto +import org.jetbrains.dukat.tsmodelproto.PropertyAccessExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.PropertyDeclarationProto +import org.jetbrains.dukat.tsmodelproto.QualifierDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ReferenceDeclarationProto +import org.jetbrains.dukat.tsmodelproto.RegExLiteralExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ReturnStatementDeclarationProto +import org.jetbrains.dukat.tsmodelproto.SourceFileDeclarationProto +import org.jetbrains.dukat.tsmodelproto.SourceBundleDeclarationProto +import org.jetbrains.dukat.tsmodelproto.SourceSetDeclarationProto +import org.jetbrains.dukat.tsmodelproto.StringLiteralExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.TopLevelDeclarationProto +import org.jetbrains.dukat.tsmodelproto.TypeAliasDeclarationProto +import org.jetbrains.dukat.tsmodelproto.TypeOfExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.TypeParameterDeclarationProto +import org.jetbrains.dukat.tsmodelproto.TypeReferenceDeclarationProto +import org.jetbrains.dukat.tsmodelproto.UnaryExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.UnknownExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.VariableDeclarationProto +import org.jetbrains.dukat.tsmodelproto.WhileStatementDeclarationProto + +fun NameDeclarationProto.convert(): NameEntity { return when { hasIdentifier() -> identifier.convert() hasQualifier() -> qualifier.convert() @@ -74,11 +125,11 @@ fun Declarations.NameEntityProto.convert(): NameEntity { } } -fun Declarations.IdentifierEntityProto.convert(): IdentifierEntity { +fun IdentifierDeclarationProto.convert(): IdentifierEntity { return IdentifierEntity(value) } -fun Declarations.QualifierEntityProto.convert(): QualifierEntity { +fun QualifierDeclarationProto.convert(): QualifierEntity { val rightProto = right left.hasIdentifier() val left = if (left.hasIdentifier()) { @@ -90,15 +141,15 @@ fun Declarations.QualifierEntityProto.convert(): QualifierEntity { return QualifierEntity(left, IdentifierEntity(rightProto.value)) } -fun Declarations.ModifierDeclarationProto.convert(): ModifierDeclaration { +fun ModifierDeclarationProto.convert(): ModifierDeclaration { return ModifierDeclaration(token) } -fun Declarations.ReferenceEntityProto.convert(): ReferenceEntity { +fun ReferenceDeclarationProto.convert(): ReferenceEntity { return ReferenceEntity(uid) } -fun Declarations.HeritageClauseDeclarationProto.convert(): HeritageClauseDeclaration { +fun HeritageClauseDeclarationProto.convert(): HeritageClauseDeclaration { return HeritageClauseDeclaration( name.convert(), typeArgumentsList.map { it.convert() }, @@ -107,7 +158,7 @@ fun Declarations.HeritageClauseDeclarationProto.convert(): HeritageClauseDeclara ) } -fun Declarations.ClassDeclarationProto.convert(): ClassDeclaration { +fun ClassDeclarationProto.convert(): ClassDeclaration { return ClassDeclaration( name.convert(), membersList.map { it.convert() }, @@ -118,7 +169,7 @@ fun Declarations.ClassDeclarationProto.convert(): ClassDeclaration { ) } -fun Declarations.InterfaceDeclarationProto.convert(): InterfaceDeclaration { +fun InterfaceDeclarationProto.convert(): InterfaceDeclaration { return InterfaceDeclaration( name.convert(), membersList.map { it.convert() }, @@ -129,13 +180,13 @@ fun Declarations.InterfaceDeclarationProto.convert(): InterfaceDeclaration { ) } -fun Declarations.BlockDeclarationProto.convert() : BlockDeclaration { +fun BlockDeclarationProto.convert() : BlockDeclaration { return BlockDeclaration( statements = statementsList.map { it.convert() } ) } -fun Declarations.FunctionDeclarationProto.convert(): FunctionDeclaration { +fun FunctionDeclarationProto.convert(): FunctionDeclaration { return FunctionDeclaration( name, parametersList.map { it.convert() }, @@ -149,7 +200,7 @@ fun Declarations.FunctionDeclarationProto.convert(): FunctionDeclaration { ) } -fun Declarations.TypeAliasDeclarationProto.convert(): TypeAliasDeclaration { +fun TypeAliasDeclarationProto.convert(): TypeAliasDeclaration { return TypeAliasDeclaration( aliasName.convert(), typeParametersList.map { it.convert() }, @@ -158,7 +209,7 @@ fun Declarations.TypeAliasDeclarationProto.convert(): TypeAliasDeclaration { ) } -fun Declarations.VariableDeclarationProto.convert(): VariableDeclaration { +fun VariableDeclarationProto.convert(): VariableDeclaration { return VariableDeclaration( name, type.convert(), @@ -170,15 +221,15 @@ fun Declarations.VariableDeclarationProto.convert(): VariableDeclaration { ) } -fun Declarations.EnumDeclaration.convert(): EnumDeclaration { +fun EnumDeclarationProto.convert(): EnumDeclaration { return EnumDeclaration(name, valuesList.map { EnumTokenDeclaration(it.value, it.meta) }) } -private fun Declarations.DefinitionInfoDeclarationProto.convert(): DefinitionInfoDeclaration { +private fun DefinitionInfoDeclarationProto.convert(): DefinitionInfoDeclaration { return DefinitionInfoDeclaration(fileName) } -fun Declarations.ModuleDeclarationProto.convert(): ModuleDeclaration { +fun ModuleDeclarationProto.convert(): ModuleDeclaration { return ModuleDeclaration(packageName.convert(), declarationsList.map { it.convert() }, modifiersList.map { it.convert() }, @@ -188,15 +239,15 @@ fun Declarations.ModuleDeclarationProto.convert(): ModuleDeclaration { root) } -fun Declarations.ExportAssignmentDeclarationProto.convert(): ExportAssignmentDeclaration { +fun ExportAssignmentDeclarationProto.convert(): ExportAssignmentDeclaration { return ExportAssignmentDeclaration(name, isExportEquals) } -fun Declarations.ImportEqualsDeclarationProto.convert(): ImportEqualsDeclaration { +fun ImportEqualsDeclarationProto.convert(): ImportEqualsDeclaration { return ImportEqualsDeclaration(name, moduleReference.convert(), uid) } -fun List.convert(): TopLevelDeclaration? { +fun List.convert(): TopLevelDeclaration? { return when { this.isEmpty() -> null this.size == 1 -> this[0].convert() @@ -204,7 +255,7 @@ fun List.convert(): TopLevelDeclaration? { } } -fun Declarations.IfStatementDeclarationProto.convert(): IfStatementDeclaration { +fun IfStatementDeclarationProto.convert(): IfStatementDeclaration { return IfStatementDeclaration( condition = condition.convert(), thenStatement = thenStatementList.convert() ?: BlockDeclaration(emptyList()), @@ -212,18 +263,18 @@ fun Declarations.IfStatementDeclarationProto.convert(): IfStatementDeclaration { ) } -fun Declarations.WhileStatementDeclarationProto.convert(): WhileStatementDeclaration { +fun WhileStatementDeclarationProto.convert(): WhileStatementDeclaration { return WhileStatementDeclaration( condition = condition.convert(), statement = statementList.convert() ?: BlockDeclaration(emptyList()) ) } -fun Declarations.ExpressionStatementDeclarationProto.convert(): ExpressionStatementDeclaration { +fun ExpressionStatementDeclarationProto.convert(): ExpressionStatementDeclaration { return ExpressionStatementDeclaration(expression.convert()) } -fun Declarations.ReturnStatementDeclarationProto.convert(): ReturnStatementDeclaration { +fun ReturnStatementDeclarationProto.convert(): ReturnStatementDeclaration { return ReturnStatementDeclaration( if(hasExpression()) { expression.convert() @@ -231,7 +282,7 @@ fun Declarations.ReturnStatementDeclarationProto.convert(): ReturnStatementDecla ) } -fun Declarations.TopLevelEntityProto.convert(): TopLevelDeclaration { +fun TopLevelDeclarationProto.convert(): TopLevelDeclaration { return when { hasClassDeclaration() -> classDeclaration.convert() hasInterfaceDeclaration() -> interfaceDeclaration.convert() @@ -251,7 +302,7 @@ fun Declarations.TopLevelEntityProto.convert(): TopLevelDeclaration { } } -fun Declarations.PropertyDeclarationProto.convert(): PropertyDeclaration { +fun PropertyDeclarationProto.convert(): PropertyDeclaration { return PropertyDeclaration( name, if (hasInitializer()) { @@ -264,14 +315,14 @@ fun Declarations.PropertyDeclarationProto.convert(): PropertyDeclaration { ) } -fun Declarations.IndexSignatureDeclarationProto.convert(): IndexSignatureDeclaration { +fun IndexSignatureDeclarationProto.convert(): IndexSignatureDeclaration { return IndexSignatureDeclaration( indexTypesList.map { it.convert() }, returnType.convert() ) } -fun Declarations.CallSignatureDeclarationProto.convert(): CallSignatureDeclaration { +fun CallSignatureDeclarationProto.convert(): CallSignatureDeclaration { return CallSignatureDeclaration( parametersList.map { it.convert() }, type.convert(), @@ -279,7 +330,7 @@ fun Declarations.CallSignatureDeclarationProto.convert(): CallSignatureDeclarati ) } -fun Declarations.MemberEntityProto.convert(): MemberDeclaration { +fun MemberDeclarationProto.convert(): MemberDeclaration { return when { hasConstructorDeclaration() -> constructorDeclaration.convert() hasMethodSignature() -> methodSignature.convert() @@ -291,7 +342,7 @@ fun Declarations.MemberEntityProto.convert(): MemberDeclaration { } } -fun Declarations.ConstructorDeclarationProto.convert(): ConstructorDeclaration { +fun ConstructorDeclarationProto.convert(): ConstructorDeclaration { return ConstructorDeclaration( parametersList.map { it.convert() }, typeParametersList.map { it.convert() }, @@ -299,7 +350,7 @@ fun Declarations.ConstructorDeclarationProto.convert(): ConstructorDeclaration { ) } -fun Declarations.MethodSignatureDeclarationProto.convert(): MethodSignatureDeclaration { +fun MethodSignatureDeclarationProto.convert(): MethodSignatureDeclaration { return MethodSignatureDeclaration( name, parametersList.map { it.convert() }, @@ -310,7 +361,7 @@ fun Declarations.MethodSignatureDeclarationProto.convert(): MethodSignatureDecla ) } -private fun Declarations.TypeParameterDeclarationProto.convert(): TypeParameterDeclaration { +private fun TypeParameterDeclarationProto.convert(): TypeParameterDeclaration { return TypeParameterDeclaration( name.convert(), constraintsList.map { constraintProto -> constraintProto.convert() }, @@ -323,7 +374,7 @@ private fun Declarations.TypeParameterDeclarationProto.convert(): TypeParameterD } -private fun Declarations.TypeReferenceDeclarationProto.convert(): TypeDeclaration { +private fun TypeReferenceDeclarationProto.convert(): TypeDeclaration { return TypeDeclaration( value.convert(), paramsList.map { it.convert() }, @@ -333,7 +384,7 @@ private fun Declarations.TypeReferenceDeclarationProto.convert(): TypeDeclaratio ) } -private fun Declarations.ParameterDeclarationProto.convert(): ParameterDeclaration { +private fun ParameterDeclarationProto.convert(): ParameterDeclaration { return ParameterDeclaration( name, type.convert(), @@ -345,7 +396,7 @@ private fun Declarations.ParameterDeclarationProto.convert(): ParameterDeclarati ) } -private fun Declarations.ParameterValueDeclarationProto.convert(): ParameterValueDeclaration { +private fun ParameterValueDeclarationProto.convert(): ParameterValueDeclaration { return when { hasStringLiteral() -> StringLiteralDeclaration(stringLiteral.token) hasThisType() -> ThisTypeDeclaration() @@ -379,7 +430,7 @@ private fun Declarations.ParameterValueDeclarationProto.convert(): ParameterValu } -fun Declarations.BinaryExpressionDeclarationProto.convert() : BinaryExpressionDeclaration { +fun BinaryExpressionDeclarationProto.convert() : BinaryExpressionDeclaration { return BinaryExpressionDeclaration( left = left.convert(), operator = operator, @@ -387,7 +438,7 @@ fun Declarations.BinaryExpressionDeclarationProto.convert() : BinaryExpressionDe ) } -fun Declarations.UnaryExpressionDeclarationProto.convert() : UnaryExpressionDeclaration { +fun UnaryExpressionDeclarationProto.convert() : UnaryExpressionDeclaration { return UnaryExpressionDeclaration( operand = operand.convert(), operator = operator, @@ -395,20 +446,20 @@ fun Declarations.UnaryExpressionDeclarationProto.convert() : UnaryExpressionDecl ) } -fun Declarations.TypeOfExpressionDeclarationProto.convert(): TypeOfExpressionDeclaration { +fun TypeOfExpressionDeclarationProto.convert(): TypeOfExpressionDeclaration { return TypeOfExpressionDeclaration( expression = expression.convert() ) } -fun Declarations.CallExpressionDeclarationProto.convert(): CallExpressionDeclaration { +fun CallExpressionDeclarationProto.convert(): CallExpressionDeclaration { return CallExpressionDeclaration( expression = expression.convert(), arguments = argumentsList.map { it.convert() } ) } -fun Declarations.NameExpressionDeclarationProto.convert() : NameExpressionDeclaration { +fun NameExpressionDeclarationProto.convert() : NameExpressionDeclaration { return when { name.hasIdentifier() -> IdentifierExpressionDeclaration(identifier = name.identifier.convert()) name.hasQualifier() -> QualifierExpressionDeclaration(qualifier = name.qualifier.convert()) @@ -416,14 +467,14 @@ fun Declarations.NameExpressionDeclarationProto.convert() : NameExpressionDeclar } } -fun Declarations.NumericLiteralExpressionDeclarationProto.convert() = NumericLiteralExpressionDeclaration(value) -fun Declarations.BigIntLiteralExpressionDeclarationProto.convert() = BigIntLiteralExpressionDeclaration(value) -fun Declarations.StringLiteralExpressionDeclarationProto.convert() = StringLiteralExpressionDeclaration(value) -fun Declarations.BooleanLiteralExpressionDeclarationProto.convert() = BooleanLiteralExpressionDeclaration(value) -fun Declarations.RegExLiteralExpressionDeclarationProto.convert() = RegExLiteralExpressionDeclaration(value) -fun Declarations.ObjectLiteralExpressionDeclarationProto.convert() = ObjectLiteralExpressionDeclaration(membersList.map { it.convert() }) +fun NumericLiteralExpressionDeclarationProto.convert() = NumericLiteralExpressionDeclaration(value) +fun BigIntLiteralExpressionDeclarationProto.convert() = BigIntLiteralExpressionDeclaration(value) +fun StringLiteralExpressionDeclarationProto.convert() = StringLiteralExpressionDeclaration(value) +fun BooleanLiteralExpressionDeclarationProto.convert() = BooleanLiteralExpressionDeclaration(value) +fun RegExLiteralExpressionDeclarationProto.convert() = RegExLiteralExpressionDeclaration(value) +fun ObjectLiteralExpressionDeclarationProto.convert() = ObjectLiteralExpressionDeclaration(membersList.map { it.convert() }) -fun Declarations.LiteralExpressionDeclarationProto.convert() : LiteralExpressionDeclaration { +fun LiteralExpressionDeclarationProto.convert() : LiteralExpressionDeclaration { return when { hasNumericLiteral() -> numericLiteral.convert() hasBigIntLiteral() -> bigIntLiteral.convert() @@ -435,34 +486,34 @@ fun Declarations.LiteralExpressionDeclarationProto.convert() : LiteralExpression } } -fun Declarations.PropertyAccessExpressionDeclarationProto.convert() : PropertyAccessExpressionDeclaration { +fun PropertyAccessExpressionDeclarationProto.convert() : PropertyAccessExpressionDeclaration { return PropertyAccessExpressionDeclaration( expression = expression.convert(), name = name.convert() ) } -fun Declarations.ElementAccessExpressionDeclarationProto.convert() : ElementAccessExpressionDeclaration { +fun ElementAccessExpressionDeclarationProto.convert() : ElementAccessExpressionDeclaration { return ElementAccessExpressionDeclaration( expression = expression.convert(), argumentExpression = argumentExpression.convert() ) } -fun Declarations.NewExpressionDeclarationProto.convert(): NewExpressionDeclaration { +fun NewExpressionDeclarationProto.convert(): NewExpressionDeclaration { return NewExpressionDeclaration( expression = expression.convert(), arguments = argumentsList.map { it.convert() } ) } -fun Declarations.UnknownExpressionDeclarationProto.convert() : UnknownExpressionDeclaration { +fun UnknownExpressionDeclarationProto.convert() : UnknownExpressionDeclaration { return UnknownExpressionDeclaration( meta = meta ) } -fun Declarations.ExpressionDeclarationProto.convert() : ExpressionDeclaration { +fun ExpressionDeclarationProto.convert() : ExpressionDeclaration { return when { hasBinaryExpression() -> binaryExpression.convert() hasUnaryExpression() -> unaryExpression.convert() @@ -478,7 +529,7 @@ fun Declarations.ExpressionDeclarationProto.convert() : ExpressionDeclaration { } } -fun Declarations.SourceFileDeclarationProto.convert(): SourceFileDeclaration { +fun SourceFileDeclarationProto.convert(): SourceFileDeclaration { return SourceFileDeclaration( fileName, root.convert(), @@ -486,10 +537,10 @@ fun Declarations.SourceFileDeclarationProto.convert(): SourceFileDeclaration { ) } -fun Declarations.SourceSetDeclarationProto.convert(): SourceSetDeclaration { +fun SourceSetDeclarationProto.convert(): SourceSetDeclaration { return SourceSetDeclaration(sourceName, sourcesList.map { it.convert() }) } -fun Declarations.SourceSetBundleProto.convert(): SourceBundleDeclaration { +fun SourceBundleDeclarationProto.convert(): SourceBundleDeclaration { return SourceBundleDeclaration(sourcesList.map { it.convert() }) } \ No newline at end of file diff --git a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeByteArrayTranslator.kt b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeByteArrayTranslator.kt index 23b98b9d7..4a5f63656 100644 --- a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeByteArrayTranslator.kt +++ b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeByteArrayTranslator.kt @@ -1,11 +1,11 @@ package org.jetbrains.dukat.ts.translator -import dukat.ast.proto.Declarations import org.jetbrains.dukat.astModel.SourceBundleModel import org.jetbrains.dukat.logger.Logging import org.jetbrains.dukat.moduleNameResolver.ModuleNameResolver import org.jetbrains.dukat.tsmodel.SourceBundleDeclaration import org.jetbrains.dukat.tsmodel.factory.convert +import org.jetbrains.dukat.tsmodelproto.SourceBundleDeclarationProto class JsRuntimeByteArrayTranslator( override val moduleNameResolver: ModuleNameResolver @@ -14,7 +14,7 @@ class JsRuntimeByteArrayTranslator( private val logger = Logging.logger(JsRuntimeByteArrayTranslator::class.simpleName.toString()) fun parse(data: ByteArray): SourceBundleDeclaration { - return Declarations.SourceSetBundleProto.parseFrom(data).convert() + return SourceBundleDeclarationProto.parseFrom(data).convert() } override fun translate(data: ByteArray): SourceBundleModel { diff --git a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeFileTranslator.kt b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeFileTranslator.kt index 838325558..557e1f325 100644 --- a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeFileTranslator.kt +++ b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeFileTranslator.kt @@ -1,11 +1,11 @@ package org.jetbrains.dukat.ts.translator -import dukat.ast.proto.Declarations import org.jetbrains.dukat.astModel.SourceBundleModel import org.jetbrains.dukat.logger.Logging import org.jetbrains.dukat.moduleNameResolver.ModuleNameResolver import org.jetbrains.dukat.tsmodel.SourceBundleDeclaration import org.jetbrains.dukat.tsmodel.factory.convert +import org.jetbrains.dukat.tsmodelproto.SourceBundleDeclarationProto import java.io.InputStream import java.util.concurrent.TimeUnit @@ -30,7 +30,7 @@ class JsRuntimeFileTranslator( } private fun translateFile(fileName: String): SourceBundleDeclaration { - val proto = Declarations.SourceSetBundleProto.parseFrom(translateAsInputStream(fileName)) + val proto = SourceBundleDeclarationProto.parseFrom(translateAsInputStream(fileName)) logger.debug("${proto}") return proto.convert() } From da8614185068c741271a1b3137a920c6f71239e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Nov 2019 14:59:37 +0100 Subject: [PATCH 083/172] Add various declarations to typescript protobuf. Refractor protobuf. --- typescript/ts-converter/src/ast/AstFactory.ts | 84 +++--- typescript/ts-converter/src/converter.ts | 2 +- .../ts-model-proto/src/Declarations.proto | 262 +++++++++++++----- .../dukat/tsmodel/factory/convertProtobuf.kt | 93 ++++--- .../JsRuntimeByteArrayTranslator.kt | 4 +- .../ts/translator/JsRuntimeFileTranslator.kt | 4 +- 6 files changed, 293 insertions(+), 156 deletions(-) diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index 97f1e51c5..c4c8c5af5 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -53,7 +53,7 @@ export class AstFactory implements AstFactory { callSignature.setType(type); callSignature.setTypeparametersList(typeParams); - let memberProto = new declarations.MemberEntityProto(); + let memberProto = new declarations.MemberDeclarationProto(); memberProto.setCallsignature(callSignature); return memberProto; } @@ -67,9 +67,9 @@ export class AstFactory implements AstFactory { classDeclaration.setTypeparametersList(typeParams); classDeclaration.setParententitiesList(parentEntities); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setClassdeclaration(classDeclaration); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setClassdeclaration(classDeclaration); + return topLevelDeclaration; } createConstructorDeclaration(parameters: Array, typeParams: Array, modifiers: Array): ConstructorDeclaration { @@ -79,7 +79,7 @@ export class AstFactory implements AstFactory { constuctorDeclaration.setTypeparametersList(typeParams); constuctorDeclaration.setModifiersList(modifiers); - let memberProto = new declarations.MemberEntityProto(); + let memberProto = new declarations.MemberDeclarationProto(); memberProto.setConstructordeclaration(constuctorDeclaration); return memberProto; } @@ -91,17 +91,17 @@ export class AstFactory implements AstFactory { } createEnumDeclaration(name: string, values: Array): EnumDeclaration { - let enumDeclaration = new declarations.EnumDeclaration(); + let enumDeclaration = new declarations.EnumDeclarationProto(); enumDeclaration.setName(name); enumDeclaration.setValuesList(values); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setEnumdeclaration(enumDeclaration); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setEnumdeclaration(enumDeclaration); + return topLevelDeclaration; } createEnumTokenDeclaration(value: string, meta: string): EnumTokenDeclaration { - let enumToken = new declarations.EnumTokenDeclaration(); + let enumToken = new declarations.EnumTokenDeclarationProto(); enumToken.setValue(value); enumToken.setMeta(meta); return enumToken; @@ -112,9 +112,9 @@ export class AstFactory implements AstFactory { exportAssignment.setName(name); exportAssignment.setIsexportequals(isExportEquals); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setExportassignment(exportAssignment); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setExportassignment(exportAssignment); + return topLevelDeclaration; } createExpression(kind: TypeDeclaration, meta: string): Expression { @@ -140,7 +140,7 @@ export class AstFactory implements AstFactory { createFunctionDeclarationAsMember(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, uid: String): FunctionDeclaration { let functionDeclaration = this.createFunctionDeclaration(name, parameters, type, typeParams, modifiers, uid); - let memberProto = new declarations.MemberEntityProto(); + let memberProto = new declarations.MemberDeclarationProto(); memberProto.setFunctiondeclaration(functionDeclaration); return memberProto; } @@ -148,9 +148,9 @@ export class AstFactory implements AstFactory { createFunctionDeclarationAsTopLevel(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, uid: String): FunctionDeclaration { let functionDeclaration = this.createFunctionDeclaration(name, parameters, type, typeParams, modifiers, uid); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setFunctiondeclaration(functionDeclaration); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setFunctiondeclaration(functionDeclaration); + return topLevelDeclaration; } createFunctionTypeDeclaration(parameters: Array, type: ParameterValue): FunctionTypeDeclaration { @@ -178,15 +178,15 @@ export class AstFactory implements AstFactory { } createIdentifierDeclarationAsNameEntity(value: string): IdentifierEntity { - let identifierProto = new declarations.IdentifierEntityProto(); + let identifierProto = new declarations.IdentifierDeclarationProto(); identifierProto.setValue(value); - let nameEntity = new declarations.NameEntityProto(); + let nameEntity = new declarations.NameDeclarationProto(); nameEntity.setIdentifier(identifierProto); return nameEntity; } createIdentifierDeclaration(value: string): IdentifierEntity { - let identifierProto = new declarations.IdentifierEntityProto(); + let identifierProto = new declarations.IdentifierDeclarationProto(); identifierProto.setValue(value); return identifierProto; } @@ -197,9 +197,9 @@ export class AstFactory implements AstFactory { importEqualsDeclaration.setModulereference(moduleReference); importEqualsDeclaration.setUid(uid); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setImportequals(importEqualsDeclaration); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setImportequals(importEqualsDeclaration); + return topLevelDeclaration; } createIndexSignatureDeclaration(indexTypes: Array, returnType: ParameterValue): IndexSignatureDeclaration { @@ -207,7 +207,7 @@ export class AstFactory implements AstFactory { indexSignatureDeclaration.setIndextypesList(indexTypes); indexSignatureDeclaration.setReturntype(returnType); - let memberEntity = new declarations.MemberEntityProto(); + let memberEntity = new declarations.MemberDeclarationProto(); memberEntity.setIndexsignature(indexSignatureDeclaration); return memberEntity; } @@ -221,9 +221,9 @@ export class AstFactory implements AstFactory { interfaceDeclaration.setTypeparametersList(typeParams); interfaceDeclaration.setParententitiesList(parentEntities); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setInterfacedeclaration(interfaceDeclaration); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setInterfacedeclaration(interfaceDeclaration); + return topLevelDeclaration; } createIntersectionTypeDeclaration(params: Array): IntersectionTypeDeclaration { @@ -242,7 +242,7 @@ export class AstFactory implements AstFactory { methodDeclaration.setType(type); methodDeclaration.setTypeparamsList(typeParams); - let memberProto = new declarations.MemberEntityProto(); + let memberProto = new declarations.MemberDeclarationProto(); memberProto.setFunctionDeclarataion(memberProto); return memberProto; } @@ -256,7 +256,7 @@ export class AstFactory implements AstFactory { methodSignature.setOptional(optional); methodSignature.setModifiersList(modifiers); - let memberProto = new declarations.MemberEntityProto(); + let memberProto = new declarations.MemberDeclarationProto(); memberProto.setMethodsignature(methodSignature); return memberProto; } @@ -282,9 +282,9 @@ export class AstFactory implements AstFactory { createModuleDeclarationAsTopLevel(packageName: NameEntity, toplevels: Declaration[], modifiers: Array, definitionsInfo: Array, uid: string, resourceName: string, root: boolean): ModuleDeclaration { let module = this.createModuleDeclaration(packageName, toplevels, modifiers, definitionsInfo, uid, resourceName, root); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setModuledeclaration(module); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setModuledeclaration(module); + return topLevelDeclaration; } createObjectLiteral(members: Array): ObjectLiteral { @@ -309,17 +309,17 @@ export class AstFactory implements AstFactory { } createQualifiedNameDeclaration(left: NameEntity, right: IdentifierEntity): QualifierEntity { - let qualifier = new declarations.QualifierEntityProto(); + let qualifier = new declarations.QualifierDeclarationProto(); qualifier.setLeft(left); qualifier.setRight(right); - let nameEntity = new declarations.NameEntityProto(); + let nameEntity = new declarations.NameDeclarationProto(); nameEntity.setQualifier(qualifier); return nameEntity; } createReferenceEntity(uid: string): ReferenceEntity { - let reference = new declarations.ReferenceEntityProto(); + let reference = new declarations.ReferenceDeclarationProto(); reference.setUid(uid); return reference; } @@ -370,9 +370,9 @@ export class AstFactory implements AstFactory { typeAlias.setTypereference(typeReference); typeAlias.setUid(uid); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setAliasdeclaration(typeAlias); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setAliasdeclaration(typeAlias); + return topLevelDeclaration; } createTypeReferenceDeclaration(value: NameEntity, params: Array, typeReference: ReferenceEntity | null = null): TypeDeclaration { @@ -430,7 +430,7 @@ export class AstFactory implements AstFactory { propertyDeclaration.setOptional(optional); propertyDeclaration.setModifiersList(modifiers); - let memberProto = new declarations.MemberEntityProto(); + let memberProto = new declarations.MemberDeclarationProto(); memberProto.setProperty(propertyDeclaration); return memberProto; } @@ -442,9 +442,9 @@ export class AstFactory implements AstFactory { variableDeclaration.setModifiersList(modifiers); variableDeclaration.setUid(uid); - let topLevelEntity = new declarations.TopLevelEntityProto(); - topLevelEntity.setVariabledeclaration(variableDeclaration); - return topLevelEntity; + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setVariabledeclaration(variableDeclaration); + return topLevelDeclaration; } } \ No newline at end of file diff --git a/typescript/ts-converter/src/converter.ts b/typescript/ts-converter/src/converter.ts index a50a629a9..9bce792a4 100644 --- a/typescript/ts-converter/src/converter.ts +++ b/typescript/ts-converter/src/converter.ts @@ -74,7 +74,7 @@ export function translate(stdlib: string, packageName: string, files: Array>(); let sourceSets = files.map(fileName => createSourceSet(fileName, stdlib, packageName, libDeclarations)); - let sourceSetBundle = new declarations.SourceSetBundleProto(); + let sourceSetBundle = new declarations.SourceBundleDeclarationProto(); let astFactory = createAstFactory(); let libRootUid = ""; diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 316987c1c..161aff7d1 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -1,20 +1,26 @@ syntax = "proto3"; -package dukat.ast.proto; +package org.jetbrains.dukat.tsmodelproto; -option java_outer_classname = "Declarations"; +option java_multiple_files = true; -message DefinitionInfoDeclarationProto { - string fileName = 1; +message NameDeclarationProto { + oneof type { + IdentifierDeclarationProto identifier = 1; + QualifierDeclarationProto qualifier = 2; + } } -message EnumTokenDeclaration { +message IdentifierDeclarationProto { string value = 1; - string meta = 2; } -message EnumDeclaration { - string name = 1; - repeated EnumTokenDeclaration values = 2; +message QualifierDeclarationProto { + NameDeclarationProto left = 1; + IdentifierDeclarationProto right = 3; +} + +message DefinitionInfoDeclarationProto { + string fileName = 1; } message ExportAssignmentDeclarationProto { @@ -22,23 +28,6 @@ message ExportAssignmentDeclarationProto { bool isExportEquals = 2; } -message NameEntityProto { - oneof type { - IdentifierEntityProto identifier = 1; - QualifierEntityProto qualifier = 2; - } -} - -message IdentifierEntityProto { - string value = 1; -} - -message QualifierEntityProto { - NameEntityProto left = 1; - IdentifierEntityProto right = 3; -} - - message ParameterValueDeclarationProto { oneof type { StringLiteralDeclarationProto stringLiteral = 1; @@ -62,7 +51,7 @@ message ThisTypeDeclarationProto { message ImportEqualsDeclarationProto { string name = 1; - NameEntityProto moduleReference = 2; + NameDeclarationProto moduleReference = 2; string uid = 3; } @@ -72,7 +61,7 @@ message FunctionTypeDeclarationProto { } message TypeParameterDeclarationProto { - NameEntityProto name = 1; + NameDeclarationProto name = 1; repeated ParameterValueDeclarationProto constraints = 2; ParameterValueDeclarationProto defaultValue = 3; } @@ -90,13 +79,13 @@ message UnionTypeDeclarationProto { } message TypeReferenceDeclarationProto { - NameEntityProto value = 1; + NameDeclarationProto value = 1; repeated ParameterValueDeclarationProto params = 2; - ReferenceEntityProto typeReference = 3; + ReferenceDeclarationProto typeReference = 3; } message TypeParamReferenceDeclarationProto { - NameEntityProto value = 1; + NameDeclarationProto value = 1; } message CallSignatureDeclarationProto { @@ -111,13 +100,18 @@ message ConstructorDeclarationProto { repeated ModifierDeclarationProto modifiers = 3; } +message BlockDeclarationProto { + repeated TopLevelDeclarationProto statements = 1; +} + message FunctionDeclarationProto { string name = 1; repeated ParameterDeclarationProto parameters = 2; ParameterValueDeclarationProto type = 3; repeated TypeParameterDeclarationProto typeParameters = 4; repeated ModifierDeclarationProto modifiers = 5; - string uid = 6; + BlockDeclarationProto body = 6; + string uid = 7; } message IndexSignatureDeclarationProto { @@ -136,10 +130,11 @@ message MethodSignatureDeclarationProto { message PropertyDeclarationProto { string name = 1; - ParameterValueDeclarationProto type = 2; - repeated TypeParameterDeclarationProto typeParameters = 3; - bool optional = 4; - repeated ModifierDeclarationProto modifiers = 5; + ExpressionDeclarationProto initializer = 2; + ParameterValueDeclarationProto type = 3; + repeated TypeParameterDeclarationProto typeParameters = 4; + bool optional = 5; + repeated ModifierDeclarationProto modifiers = 6; } message ModifierDeclarationProto { @@ -147,10 +142,10 @@ message ModifierDeclarationProto { } message ObjectLiteralDeclarationProto { - repeated MemberEntityProto members = 1; + repeated MemberDeclarationProto members = 1; } -message MemberEntityProto { +message MemberDeclarationProto { oneof type { CallSignatureDeclarationProto callSignature = 1; ConstructorDeclarationProto constructorDeclaration = 2; @@ -162,15 +157,113 @@ message MemberEntityProto { } } -message ReferenceEntityProto { +message ReferenceDeclarationProto { string uid = 1; } +message StringLiteralExpressionDeclarationProto { + string value = 1; +} + +message BooleanLiteralExpressionDeclarationProto { + bool value = 1; +} + +message NumericLiteralExpressionDeclarationProto { + string value = 1; +} + +message BigIntLiteralExpressionDeclarationProto { + string value = 1; +} + +message ObjectLiteralExpressionDeclarationProto { + repeated MemberDeclarationProto members = 1; +} + +message RegExLiteralExpressionDeclarationProto { + string value = 1; +} + +message LiteralExpressionDeclarationProto { + oneof type { + StringLiteralExpressionDeclarationProto stringLiteral = 1; + BooleanLiteralExpressionDeclarationProto booleanLiteral = 2; + NumericLiteralExpressionDeclarationProto numericLiteral = 3; + BigIntLiteralExpressionDeclarationProto bigIntLiteral = 4; + ObjectLiteralExpressionDeclarationProto objectLiteral = 5; + RegExLiteralExpressionDeclarationProto regExLiteral = 6; + } +} + +message NameExpressionDeclarationProto { + NameDeclarationProto name = 1; +} + +message BinaryExpressionDeclarationProto { + ExpressionDeclarationProto left = 1; + string operator = 2; + ExpressionDeclarationProto right = 3; +} + +message UnaryExpressionDeclarationProto { + ExpressionDeclarationProto operand = 1; + string operator = 2; + bool isPrefix = 3; +} + +message TypeOfExpressionDeclarationProto { + ExpressionDeclarationProto expression = 1; +} + +message CallExpressionDeclarationProto { + ExpressionDeclarationProto expression = 1; + repeated ExpressionDeclarationProto arguments = 2; +} + +message PropertyAccessExpressionDeclarationProto { + ExpressionDeclarationProto expression = 1; + IdentifierDeclarationProto name = 2; +} + +message ElementAccessExpressionDeclarationProto { + ExpressionDeclarationProto expression = 1; + ExpressionDeclarationProto argumentExpression = 2; +} + +message NewExpressionDeclarationProto { + ExpressionDeclarationProto expression = 1; + repeated ExpressionDeclarationProto arguments = 2; +} + +message UnknownExpressionDeclarationProto { + string meta = 1; +} + message ExpressionDeclarationProto { TypeReferenceDeclarationProto kind = 1; string meta = 2; } +message ExpressionStatementDeclarationProto { + ExpressionDeclarationProto expression = 1; +} + +message IfStatementDeclarationProto { + ExpressionDeclarationProto condition = 1; + repeated TopLevelDeclarationProto thenStatement = 2; + repeated TopLevelDeclarationProto elseStatement = 3; +} + +message WhileStatementDeclarationProto { + ExpressionDeclarationProto condition = 1; + repeated TopLevelDeclarationProto statement = 2; +} + +message ReturnStatementDeclarationProto { + ExpressionDeclarationProto expression = 1; +} + message ParameterDeclarationProto { string name = 1; ParameterValueDeclarationProto type = 2; @@ -183,77 +276,92 @@ message VariableDeclarationProto { string name = 1; ParameterValueDeclarationProto type = 2; repeated ModifierDeclarationProto modifiers = 3; - string uid = 4; + ExpressionDeclarationProto initializer = 4; + string uid = 5; } message TypeAliasDeclarationProto { - NameEntityProto aliasName = 1; - repeated IdentifierEntityProto typeParameters = 2; + NameDeclarationProto aliasName = 1; + repeated IdentifierDeclarationProto typeParameters = 2; ParameterValueDeclarationProto typeReference = 3; string uid = 4; } message HeritageClauseDeclarationProto { - NameEntityProto name = 1; + NameDeclarationProto name = 1; repeated ParameterValueDeclarationProto typeArguments = 2; bool extending = 3; - ReferenceEntityProto typeReference = 4; + ReferenceDeclarationProto typeReference = 4; } -message SourceFileDeclarationProto { - string fileName = 1; - ModuleDeclarationProto root = 2; - repeated IdentifierEntityProto referencedFiles = 3; +message EnumTokenDeclarationProto { + string value = 1; + string meta = 2; } -message SourceSetDeclarationProto { - string sourceName = 1; - repeated SourceFileDeclarationProto sources = 2; +message EnumDeclarationProto { + string name = 1; + repeated EnumTokenDeclarationProto values = 2; } -message SourceSetBundleProto { - repeated SourceSetDeclarationProto sources = 1; +message ClassDeclarationProto { + NameDeclarationProto name = 1; + repeated MemberDeclarationProto members = 2; + repeated TypeParameterDeclarationProto typeParameters = 3; + repeated HeritageClauseDeclarationProto parentEntities = 4; + repeated ModifierDeclarationProto modifiers = 5; + string uid = 6; } -message ModuleDeclarationProto { - NameEntityProto packageName = 1; - repeated TopLevelEntityProto declarations = 2; - repeated ModifierDeclarationProto modifiers = 3; - repeated DefinitionInfoDeclarationProto definitionsInfo = 4; - string uid = 5; - string resourceName = 6; - bool root = 7; +message InterfaceDeclarationProto { + NameDeclarationProto name = 1; + repeated MemberDeclarationProto members = 2; + repeated TypeParameterDeclarationProto typeParameters = 3; + repeated HeritageClauseDeclarationProto parentEntities = 4; + repeated DefinitionInfoDeclarationProto definitionsInfo = 5; + string uid = 6; } -message TopLevelEntityProto { +message TopLevelDeclarationProto { oneof type { ClassDeclarationProto classDeclaration = 1; InterfaceDeclarationProto interfaceDeclaration = 2; VariableDeclarationProto variableDeclaration = 3; FunctionDeclarationProto functionDeclaration = 4; TypeAliasDeclarationProto aliasDeclaration = 5; - EnumDeclaration enumDeclaration = 6; + EnumDeclarationProto enumDeclaration = 6; ModuleDeclarationProto moduleDeclaration = 7; ExportAssignmentDeclarationProto exportAssignment = 8; ImportEqualsDeclarationProto importEquals = 9; + ExpressionStatementDeclarationProto expressionStatement = 10; + ReturnStatementDeclarationProto returnStatement = 11; + BlockDeclarationProto blockStatement = 12; + IfStatementDeclarationProto ifStatement = 13; + WhileStatementDeclarationProto whileStatement = 14; } } -message ClassDeclarationProto { - NameEntityProto name = 1; - repeated MemberEntityProto members = 2; - repeated TypeParameterDeclarationProto typeParameters = 3; - repeated HeritageClauseDeclarationProto parentEntities = 4; - repeated ModifierDeclarationProto modifiers = 5; - string uid = 6; +message ModuleDeclarationProto { + NameDeclarationProto packageName = 1; + repeated TopLevelDeclarationProto declarations = 2; + repeated ModifierDeclarationProto modifiers = 3; + repeated DefinitionInfoDeclarationProto definitionsInfo = 4; + string uid = 5; + string resourceName = 6; + bool root = 7; } +message SourceFileDeclarationProto { + string fileName = 1; + ModuleDeclarationProto root = 2; + repeated IdentifierDeclarationProto referencedFiles = 3; +} -message InterfaceDeclarationProto { - NameEntityProto name = 1; - repeated MemberEntityProto members = 2; - repeated TypeParameterDeclarationProto typeParameters = 3; - repeated HeritageClauseDeclarationProto parentEntities = 4; - repeated DefinitionInfoDeclarationProto definitionsInfo = 5; - string uid = 6; +message SourceSetDeclarationProto { + string sourceName = 1; + repeated SourceFileDeclarationProto sources = 2; +} + +message SourceBundleDeclarationProto { + repeated SourceSetDeclarationProto sources = 1; } \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index cf45f4d38..fd243318a 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -1,6 +1,5 @@ package org.jetbrains.dukat.tsmodel.factory -import dukat.ast.proto.Declarations import org.jetbrains.dukat.astCommon.Entity import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.astCommon.NameEntity @@ -42,8 +41,38 @@ import org.jetbrains.dukat.tsmodel.types.TupleDeclaration import org.jetbrains.dukat.tsmodel.types.TypeDeclaration import org.jetbrains.dukat.tsmodel.types.TypeParamReferenceDeclaration import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration - -fun Declarations.NameEntityProto.convert(): NameEntity { +import org.jetbrains.dukat.tsmodelproto.CallSignatureDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ClassDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ConstructorDeclarationProto +import org.jetbrains.dukat.tsmodelproto.DefinitionInfoDeclarationProto +import org.jetbrains.dukat.tsmodelproto.EnumDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ExportAssignmentDeclarationProto +import org.jetbrains.dukat.tsmodelproto.FunctionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.HeritageClauseDeclarationProto +import org.jetbrains.dukat.tsmodelproto.IdentifierDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ImportEqualsDeclarationProto +import org.jetbrains.dukat.tsmodelproto.IndexSignatureDeclarationProto +import org.jetbrains.dukat.tsmodelproto.InterfaceDeclarationProto +import org.jetbrains.dukat.tsmodelproto.MemberDeclarationProto +import org.jetbrains.dukat.tsmodelproto.MethodSignatureDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ModifierDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ModuleDeclarationProto +import org.jetbrains.dukat.tsmodelproto.NameDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ParameterDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ParameterValueDeclarationProto +import org.jetbrains.dukat.tsmodelproto.PropertyDeclarationProto +import org.jetbrains.dukat.tsmodelproto.QualifierDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ReferenceDeclarationProto +import org.jetbrains.dukat.tsmodelproto.SourceBundleDeclarationProto +import org.jetbrains.dukat.tsmodelproto.SourceFileDeclarationProto +import org.jetbrains.dukat.tsmodelproto.SourceSetDeclarationProto +import org.jetbrains.dukat.tsmodelproto.TopLevelDeclarationProto +import org.jetbrains.dukat.tsmodelproto.TypeAliasDeclarationProto +import org.jetbrains.dukat.tsmodelproto.TypeParameterDeclarationProto +import org.jetbrains.dukat.tsmodelproto.TypeReferenceDeclarationProto +import org.jetbrains.dukat.tsmodelproto.VariableDeclarationProto + +fun NameDeclarationProto.convert(): NameEntity { return when { hasIdentifier() -> identifier.convert() hasQualifier() -> qualifier.convert() @@ -51,11 +80,11 @@ fun Declarations.NameEntityProto.convert(): NameEntity { } } -fun Declarations.IdentifierEntityProto.convert(): IdentifierEntity { +fun IdentifierDeclarationProto.convert(): IdentifierEntity { return IdentifierEntity(value) } -fun Declarations.QualifierEntityProto.convert(): QualifierEntity { +fun QualifierDeclarationProto.convert(): QualifierEntity { val rightProto = right left.hasIdentifier() val left = if (left.hasIdentifier()) { @@ -67,15 +96,15 @@ fun Declarations.QualifierEntityProto.convert(): QualifierEntity { return QualifierEntity(left, IdentifierEntity(rightProto.value)) } -fun Declarations.ModifierDeclarationProto.convert(): ModifierDeclaration { +fun ModifierDeclarationProto.convert(): ModifierDeclaration { return ModifierDeclaration(token) } -fun Declarations.ReferenceEntityProto.convert(): ReferenceEntity { +fun ReferenceDeclarationProto.convert(): ReferenceEntity { return ReferenceEntity(uid) } -fun Declarations.HeritageClauseDeclarationProto.convert(): HeritageClauseDeclaration { +fun HeritageClauseDeclarationProto.convert(): HeritageClauseDeclaration { return HeritageClauseDeclaration( name.convert(), typeArgumentsList.map { it.convert() }, @@ -84,7 +113,7 @@ fun Declarations.HeritageClauseDeclarationProto.convert(): HeritageClauseDeclara ) } -fun Declarations.ClassDeclarationProto.convert(): ClassDeclaration { +fun ClassDeclarationProto.convert(): ClassDeclaration { return ClassDeclaration( name.convert(), membersList.map { it.convert() }, @@ -95,7 +124,7 @@ fun Declarations.ClassDeclarationProto.convert(): ClassDeclaration { ) } -fun Declarations.InterfaceDeclarationProto.convert(): InterfaceDeclaration { +fun InterfaceDeclarationProto.convert(): InterfaceDeclaration { return InterfaceDeclaration( name.convert(), membersList.map { it.convert() }, @@ -106,7 +135,7 @@ fun Declarations.InterfaceDeclarationProto.convert(): InterfaceDeclaration { ) } -fun Declarations.FunctionDeclarationProto.convert(): FunctionDeclaration { +fun FunctionDeclarationProto.convert(): FunctionDeclaration { return FunctionDeclaration( name, parametersList.map { it.convert() }, @@ -117,7 +146,7 @@ fun Declarations.FunctionDeclarationProto.convert(): FunctionDeclaration { ) } -fun Declarations.TypeAliasDeclarationProto.convert(): TypeAliasDeclaration { +fun TypeAliasDeclarationProto.convert(): TypeAliasDeclaration { return TypeAliasDeclaration( aliasName.convert(), typeParametersList.map { it.convert() }, @@ -126,19 +155,19 @@ fun Declarations.TypeAliasDeclarationProto.convert(): TypeAliasDeclaration { ) } -fun Declarations.VariableDeclarationProto.convert(): VariableDeclaration { +fun VariableDeclarationProto.convert(): VariableDeclaration { return VariableDeclaration(name, type.convert(), modifiersList.map { it.convert() }, uid) } -fun Declarations.EnumDeclaration.convert(): EnumDeclaration { +fun EnumDeclarationProto.convert(): EnumDeclaration { return EnumDeclaration(name, valuesList.map { EnumTokenDeclaration(it.value, it.meta) }) } -private fun Declarations.DefinitionInfoDeclarationProto.convert(): DefinitionInfoDeclaration { +private fun DefinitionInfoDeclarationProto.convert(): DefinitionInfoDeclaration { return DefinitionInfoDeclaration(fileName) } -fun Declarations.ModuleDeclarationProto.convert(): ModuleDeclaration { +fun ModuleDeclarationProto.convert(): ModuleDeclaration { return ModuleDeclaration(packageName.convert(), declarationsList.map { it.convert() }, modifiersList.map { it.convert() }, @@ -148,15 +177,15 @@ fun Declarations.ModuleDeclarationProto.convert(): ModuleDeclaration { root) } -fun Declarations.ExportAssignmentDeclarationProto.convert(): ExportAssignmentDeclaration { +fun ExportAssignmentDeclarationProto.convert(): ExportAssignmentDeclaration { return ExportAssignmentDeclaration(name, isExportEquals) } -fun Declarations.ImportEqualsDeclarationProto.convert(): ImportEqualsDeclaration { +fun ImportEqualsDeclarationProto.convert(): ImportEqualsDeclaration { return ImportEqualsDeclaration(name, moduleReference.convert(), uid) } -fun Declarations.TopLevelEntityProto.convert(): TopLevelDeclaration { +fun TopLevelDeclarationProto.convert(): TopLevelDeclaration { return when { hasClassDeclaration() -> classDeclaration.convert() hasInterfaceDeclaration() -> interfaceDeclaration.convert() @@ -171,7 +200,7 @@ fun Declarations.TopLevelEntityProto.convert(): TopLevelDeclaration { } } -fun Declarations.PropertyDeclarationProto.convert(): PropertyDeclaration { +fun PropertyDeclarationProto.convert(): PropertyDeclaration { return PropertyDeclaration( name, type.convert(), @@ -181,14 +210,14 @@ fun Declarations.PropertyDeclarationProto.convert(): PropertyDeclaration { ) } -fun Declarations.IndexSignatureDeclarationProto.convert(): IndexSignatureDeclaration { +fun IndexSignatureDeclarationProto.convert(): IndexSignatureDeclaration { return IndexSignatureDeclaration( indexTypesList.map { it.convert() }, returnType.convert() ) } -fun Declarations.CallSignatureDeclarationProto.convert(): CallSignatureDeclaration { +fun CallSignatureDeclarationProto.convert(): CallSignatureDeclaration { return CallSignatureDeclaration( parametersList.map { it.convert() }, type.convert(), @@ -196,7 +225,7 @@ fun Declarations.CallSignatureDeclarationProto.convert(): CallSignatureDeclarati ) } -fun Declarations.MemberEntityProto.convert(): MemberDeclaration { +fun MemberDeclarationProto.convert(): MemberDeclaration { return when { hasConstructorDeclaration() -> constructorDeclaration.convert() hasMethodSignature() -> methodSignature.convert() @@ -208,7 +237,7 @@ fun Declarations.MemberEntityProto.convert(): MemberDeclaration { } } -fun Declarations.ConstructorDeclarationProto.convert(): ConstructorDeclaration { +fun ConstructorDeclarationProto.convert(): ConstructorDeclaration { return ConstructorDeclaration( parametersList.map { it.convert() }, typeParametersList.map { it.convert() }, @@ -216,7 +245,7 @@ fun Declarations.ConstructorDeclarationProto.convert(): ConstructorDeclaration { ) } -fun Declarations.MethodSignatureDeclarationProto.convert(): MethodSignatureDeclaration { +fun MethodSignatureDeclarationProto.convert(): MethodSignatureDeclaration { return MethodSignatureDeclaration( name, parametersList.map { it.convert() }, @@ -227,7 +256,7 @@ fun Declarations.MethodSignatureDeclarationProto.convert(): MethodSignatureDecla ) } -private fun Declarations.TypeParameterDeclarationProto.convert(): TypeParameterDeclaration { +private fun TypeParameterDeclarationProto.convert(): TypeParameterDeclaration { return TypeParameterDeclaration( name.convert(), constraintsList.map { constraintProto -> constraintProto.convert() }, @@ -240,7 +269,7 @@ private fun Declarations.TypeParameterDeclarationProto.convert(): TypeParameterD } -private fun Declarations.TypeReferenceDeclarationProto.convert(): TypeDeclaration { +private fun TypeReferenceDeclarationProto.convert(): TypeDeclaration { return TypeDeclaration( value.convert(), paramsList.map { it.convert() }, @@ -250,7 +279,7 @@ private fun Declarations.TypeReferenceDeclarationProto.convert(): TypeDeclaratio ) } -private fun Declarations.ParameterDeclarationProto.convert(): ParameterDeclaration { +private fun ParameterDeclarationProto.convert(): ParameterDeclaration { return ParameterDeclaration( name, type.convert(), @@ -262,7 +291,7 @@ private fun Declarations.ParameterDeclarationProto.convert(): ParameterDeclarati ) } -private fun Declarations.ParameterValueDeclarationProto.convert(): ParameterValueDeclaration { +private fun ParameterValueDeclarationProto.convert(): ParameterValueDeclaration { return when { hasStringLiteral() -> StringLiteralDeclaration(stringLiteral.token) hasThisType() -> ThisTypeDeclaration() @@ -295,7 +324,7 @@ private fun Declarations.ParameterValueDeclarationProto.convert(): ParameterValu } } -fun Declarations.SourceFileDeclarationProto.convert(): SourceFileDeclaration { +fun SourceFileDeclarationProto.convert(): SourceFileDeclaration { return SourceFileDeclaration( fileName, root.convert(), @@ -303,10 +332,10 @@ fun Declarations.SourceFileDeclarationProto.convert(): SourceFileDeclaration { ) } -fun Declarations.SourceSetDeclarationProto.convert(): SourceSetDeclaration { +fun SourceSetDeclarationProto.convert(): SourceSetDeclaration { return SourceSetDeclaration(sourceName, sourcesList.map { it.convert() }) } -fun Declarations.SourceSetBundleProto.convert(): SourceBundleDeclaration { +fun SourceBundleDeclarationProto.convert(): SourceBundleDeclaration { return SourceBundleDeclaration(sourcesList.map { it.convert() }) } \ No newline at end of file diff --git a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeByteArrayTranslator.kt b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeByteArrayTranslator.kt index 23b98b9d7..4a5f63656 100644 --- a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeByteArrayTranslator.kt +++ b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeByteArrayTranslator.kt @@ -1,11 +1,11 @@ package org.jetbrains.dukat.ts.translator -import dukat.ast.proto.Declarations import org.jetbrains.dukat.astModel.SourceBundleModel import org.jetbrains.dukat.logger.Logging import org.jetbrains.dukat.moduleNameResolver.ModuleNameResolver import org.jetbrains.dukat.tsmodel.SourceBundleDeclaration import org.jetbrains.dukat.tsmodel.factory.convert +import org.jetbrains.dukat.tsmodelproto.SourceBundleDeclarationProto class JsRuntimeByteArrayTranslator( override val moduleNameResolver: ModuleNameResolver @@ -14,7 +14,7 @@ class JsRuntimeByteArrayTranslator( private val logger = Logging.logger(JsRuntimeByteArrayTranslator::class.simpleName.toString()) fun parse(data: ByteArray): SourceBundleDeclaration { - return Declarations.SourceSetBundleProto.parseFrom(data).convert() + return SourceBundleDeclarationProto.parseFrom(data).convert() } override fun translate(data: ByteArray): SourceBundleModel { diff --git a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeFileTranslator.kt b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeFileTranslator.kt index 838325558..557e1f325 100644 --- a/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeFileTranslator.kt +++ b/typescript/ts-translator/src/org/jetbrains/dukat/ts/translator/JsRuntimeFileTranslator.kt @@ -1,11 +1,11 @@ package org.jetbrains.dukat.ts.translator -import dukat.ast.proto.Declarations import org.jetbrains.dukat.astModel.SourceBundleModel import org.jetbrains.dukat.logger.Logging import org.jetbrains.dukat.moduleNameResolver.ModuleNameResolver import org.jetbrains.dukat.tsmodel.SourceBundleDeclaration import org.jetbrains.dukat.tsmodel.factory.convert +import org.jetbrains.dukat.tsmodelproto.SourceBundleDeclarationProto import java.io.InputStream import java.util.concurrent.TimeUnit @@ -30,7 +30,7 @@ class JsRuntimeFileTranslator( } private fun translateFile(fileName: String): SourceBundleDeclaration { - val proto = Declarations.SourceSetBundleProto.parseFrom(translateAsInputStream(fileName)) + val proto = SourceBundleDeclarationProto.parseFrom(translateAsInputStream(fileName)) logger.debug("${proto}") return proto.convert() } From dda90e8ac1e9d024820f4b90d8a7bbb11db0db4a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 18 Nov 2019 14:18:18 +0100 Subject: [PATCH 084/172] Add typescript declarations for AST protobuf --- typescript/ts-converter/build.gradle | 2 +- typescript/ts-converter/src/AstConverter.ts | 90 +++---- typescript/ts-converter/src/ast/AstFactory.ts | 129 +++++----- typescript/ts-converter/src/ast/ast.ts | 226 +++++------------- typescript/ts-converter/src/toNameEntity.ts | 24 -- typescript/ts-converter/tsconfig.json | 3 +- typescript/ts-converter/webpack.config.js | 2 +- typescript/ts-model-proto/build.gradle | 63 ++++- 8 files changed, 215 insertions(+), 324 deletions(-) delete mode 100644 typescript/ts-converter/src/toNameEntity.ts diff --git a/typescript/ts-converter/build.gradle b/typescript/ts-converter/build.gradle index 8616b1d0f..da55a471b 100644 --- a/typescript/ts-converter/build.gradle +++ b/typescript/ts-converter/build.gradle @@ -56,7 +56,7 @@ task webpack(type: NodeTask) { def scriptName = "${project.buildDir}/package/node_modules/webpack/bin/webpack.js" inputs.file(scriptName) - inputs.file("${project(":ts-model-proto").buildDir}/generated/source/proto/main/js/Declarations_pb.js") + inputs.dir("${project(":ts-model-proto").buildDir}/generated/source/proto/main/js") inputs.dir("${project.buildDir}/ts") inputs.dir("${project.buildDir}/package/node_modules") diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index 724a01f59..e34575591 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -4,29 +4,19 @@ import * as ts from "typescript-services-api"; import {createLogger} from "./Logger"; import {uid} from "./uid"; import { - ClassDeclaration, - Declaration, DefinitionInfoDeclaration, Expression, - FunctionDeclaration, HeritageClauseDeclaration, - IdentifierEntity, - InterfaceDeclaration, + IdentifierDeclaration, MemberDeclaration, - MethodSignatureDeclaration, ModifierDeclaration, ModuleDeclaration, - ModuleReferenceDeclaration, NameEntity, - ObjectLiteral, ParameterDeclaration, - ParameterValue, - PropertyDeclaration, - QualifierEntity, ReferenceEntity, SourceFileDeclaration, SourceSet, - TypeAliasDeclaration, + Declaration, TypeDeclaration, TypeParameter } from "./ast/ast"; @@ -49,7 +39,7 @@ export class AstConverter { ) { } - private registerDeclaration(declaration: Declaration, collection: Array) { + private registerDeclaration(declaration: T, collection: Array) { collection.push(declaration); } @@ -106,7 +96,7 @@ export class AstConverter { return this.astFactory.createModuleDeclaration(packageName, declarations, modifiers, definitionsInfo, uid, resourceName, root); } - createModuleDeclarationAsTopLevel(packageName: NameEntity, declarations: Declaration[], modifiers: Array, definitionsInfo: Array, uid: string, resourceName: string, root: boolean): ModuleDeclaration { + createModuleDeclarationAsTopLevel(packageName: NameEntity, declarations: Declaration[], modifiers: Array, definitionsInfo: Array, uid: string, resourceName: string, root: boolean): Declaration { return this.astFactory.createModuleDeclarationAsTopLevel(packageName, declarations, modifiers, definitionsInfo, uid, resourceName, root); } @@ -122,7 +112,7 @@ export class AstConverter { return null } - convertPropertyDeclaration(nativePropertyDeclaration: (ts.PropertyDeclaration | ts.ParameterDeclaration)): PropertyDeclaration | null { + convertPropertyDeclaration(nativePropertyDeclaration: (ts.PropertyDeclaration | ts.ParameterDeclaration)): MemberDeclaration | null { let name = this.convertName(nativePropertyDeclaration.name); if (name != null) { @@ -154,8 +144,8 @@ export class AstConverter { return typeParameterDeclarations; } - convertTypeParamsToTokens(nativeTypeDeclarations: ts.NodeArray | undefined): Array { - let typeParameterDeclarations: Array = []; + convertTypeParamsToTokens(nativeTypeDeclarations: ts.NodeArray | undefined): Array { + let typeParameterDeclarations: Array = []; if (nativeTypeDeclarations) { typeParameterDeclarations = nativeTypeDeclarations.map(typeParam => { @@ -166,7 +156,7 @@ export class AstConverter { return typeParameterDeclarations; } - convertFunctionDeclaration(functionDeclaration: ts.FunctionDeclaration): FunctionDeclaration | null { + convertFunctionDeclaration(functionDeclaration: ts.FunctionDeclaration): Declaration | null { let typeParameterDeclarations: Array = this.convertTypeParams(functionDeclaration.typeParameters); @@ -219,7 +209,7 @@ export class AstConverter { } - convertMethodSignatureDeclaration(declaration: ts.MethodSignature): MethodSignatureDeclaration | null { + convertMethodSignatureDeclaration(declaration: ts.MethodSignature): MemberDeclaration | null { let typeParameterDeclarations: Array = this.convertTypeParams(declaration.typeParameters); let parameterDeclarations = declaration.parameters @@ -243,7 +233,7 @@ export class AstConverter { } - convertMethodDeclaration(declaration: ts.MethodSignature): FunctionDeclaration | null { + convertMethodDeclaration(declaration: ts.MethodSignature): MemberDeclaration | null { let typeParameterDeclarations: Array = this.convertTypeParams(declaration.typeParameters); let parameterDeclarations = declaration.parameters @@ -267,20 +257,20 @@ export class AstConverter { } - createMethodDeclaration(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array): FunctionDeclaration { + createMethodDeclaration(name: string, parameters: Array, type: TypeDeclaration, typeParams: Array, modifiers: Array): MemberDeclaration { // TODO: reintroduce method declaration return this.astFactory.createFunctionDeclarationAsMember(name, parameters, type, typeParams, modifiers, "__NO_UID__"); } - private createTypeDeclaration(value: string, params: Array = [], typeReference: string | null = null): TypeDeclaration { + private createTypeDeclaration(value: string, params: Array = [], typeReference: string | null = null): TypeDeclaration { return this.astFactory.createTypeReferenceDeclarationAsParamValue(this.astFactory.createIdentifierDeclarationAsNameEntity(value), params, null); } - createParameterDeclaration(name: string, type: ParameterValue, initializer: Expression | null, vararg: boolean, optional: boolean): ParameterDeclaration { + createParameterDeclaration(name: string, type: TypeDeclaration, initializer: Expression | null, vararg: boolean, optional: boolean): ParameterDeclaration { return this.astFactory.createParameterDeclaration(name, type, initializer, vararg, optional); } - private createProperty(value: string, type: ParameterValue, typeParams: Array = [], optional: boolean): PropertyDeclaration { + private createProperty(value: string, type: TypeDeclaration, typeParams: Array = [], optional: boolean): MemberDeclaration { return this.astFactory.declareProperty(value, type, typeParams, optional, []); } @@ -293,7 +283,7 @@ export class AstConverter { if (ts.isQualifiedName(entityName)) { return this.astFactory.createQualifiedNameDeclaration( this.convertEntityName(entityName.left), - (this.convertEntityName(entityName.right) as any).getIdentifier() + this.convertEntityName(entityName.right).getIdentifier()! ) } @@ -311,33 +301,27 @@ export class AstConverter { } } - convertType(type: ts.TypeNode | ts.Identifier | undefined): ParameterValue { + convertType(type: ts.TypeNode | undefined): TypeDeclaration { if (type == undefined) { return this.createTypeDeclaration("Any") } else { - if (ts.isIdentifier(type)) { - return this.astFactory.createIdentifierDeclarationAsNameEntity(type.text) - } - this.libVisitor.process(type); if (type.kind == ts.SyntaxKind.VoidKeyword) { return this.createTypeDeclaration("Unit") } else if (ts.isArrayTypeNode(type)) { let arrayType = type as ts.ArrayTypeNode; - return this.createTypeDeclaration("@@ArraySugar", [ - this.convertType(arrayType.elementType) - ] as Array) + return this.createTypeDeclaration("@@ArraySugar", [this.convertType(arrayType.elementType)]) } else if (ts.isUnionTypeNode(type)) { let unionTypeNode = type as ts.UnionTypeNode; let params = unionTypeNode.types - .map(argumentType => this.convertType(argumentType)) as Array; + .map(argumentType => this.convertType(argumentType)); return this.astFactory.createUnionTypeDeclaration(params) } else if (ts.isIntersectionTypeNode(type)) { let intersectionTypeNode = type as ts.IntersectionTypeNode; let params = intersectionTypeNode.types - .map(argumentType => this.convertType(argumentType)) as Array; + .map(argumentType => this.convertType(argumentType)); return this.createIntersectionType(params); } else if (ts.isTypeReferenceNode(type)) { @@ -437,7 +421,7 @@ export class AstConverter { ); } - convertTypeElementToMethodSignatureDeclaration(methodDeclaration: ts.MethodSignature): MethodSignatureDeclaration | null { + convertTypeElementToMethodSignatureDeclaration(methodDeclaration: ts.MethodSignature): MemberDeclaration | null { let convertedMethodDeclaration = this.convertMethodSignatureDeclaration(methodDeclaration); if (convertedMethodDeclaration != null) { return convertedMethodDeclaration @@ -561,7 +545,7 @@ export class AstConverter { } - convertTypeLiteralToInterfaceDeclaration(name: string, typeLiteral: ts.TypeLiteralNode, typeParams: ts.NodeArray | undefined): InterfaceDeclaration { + convertTypeLiteralToInterfaceDeclaration(name: string, typeLiteral: ts.TypeLiteralNode, typeParams: ts.NodeArray | undefined): Declaration { return this.astFactory.createInterfaceDeclaration( this.astFactory.createIdentifierDeclarationAsNameEntity(name), this.convertMembersToInterfaceMemberDeclarations(typeLiteral.members), @@ -572,7 +556,7 @@ export class AstConverter { ); } - convertTypeLiteralToObjectLiteralDeclaration(typeLiteral: ts.TypeLiteralNode): ObjectLiteral { + convertTypeLiteralToObjectLiteralDeclaration(typeLiteral: ts.TypeLiteralNode): TypeDeclaration { return this.astFactory.createObjectLiteral( this.convertMembersToInterfaceMemberDeclarations(typeLiteral.members) ); @@ -609,17 +593,16 @@ export class AstConverter { return res; } - private convertTypeAliasDeclaration(declaration: ts.TypeAliasDeclaration): TypeAliasDeclaration { - + private convertTypeAliasDeclaration(declaration: ts.TypeAliasDeclaration): Declaration { return this.astFactory.createTypeAliasDeclaration( - this.convertType(declaration.name) as NameEntity, + this.convertEntityName(declaration.name), this.convertTypeParamsToTokens(declaration.typeParameters), this.convertType(declaration.type), this.exportContext.getUID(declaration) ) } - private convertPropertyAccessExpression(propertyAccessExpression: ts.PropertyAccessExpression): QualifierEntity { + private convertPropertyAccessExpression(propertyAccessExpression: ts.PropertyAccessExpression): NameEntity { let convertedExpression: NameEntity | null; let name = this.astFactory.createIdentifierDeclaration(propertyAccessExpression.name.text); @@ -635,11 +618,6 @@ export class AstConverter { return this.astFactory.createQualifiedNameDeclaration(convertedExpression, name); } - private convertValue(entity: ts.TypeNode): NameEntity { - let convertedEntity = this.convertType(entity) as any; - return convertedEntity.getValue() as NameEntity; - } - convertHeritageClauses(heritageClauses: ts.NodeArray | undefined): Array { let parentEntities: Array = []; @@ -650,7 +628,7 @@ export class AstConverter { let extending = heritageClause.token == ts.SyntaxKind.ExtendsKeyword; for (let type of heritageClause.types) { - let typeArguments: Array = []; + let typeArguments: Array = []; if (type.typeArguments) { for (let typeArgument of type.typeArguments) { @@ -695,12 +673,12 @@ export class AstConverter { return parentEntities } - convertClassDeclaration(statement: ts.ClassDeclaration): ClassDeclaration | null { + convertClassDeclaration(statement: ts.ClassDeclaration): Declaration | null { if (statement.name == undefined) { return null; } - let classDeclaration = this.astFactory.createClassDeclaration( + return this.astFactory.createClassDeclaration( this.astFactory.createIdentifierDeclarationAsNameEntity(statement.name.getText()), this.convertClassElementsToMembers(statement.members), this.convertTypeParams(statement.typeParameters), @@ -708,8 +686,6 @@ export class AstConverter { this.convertModifiers(statement.modifiers), this.exportContext.getUID(statement) ); - - return classDeclaration; } private convertDefinitions(kind: ts.SyntaxKind, name: ts.Node): Array { @@ -725,8 +701,8 @@ export class AstConverter { return definitionsInfoDeclarations; } - convertInterfaceDeclaration(statement: ts.InterfaceDeclaration, computeDefinitions: boolean = true): InterfaceDeclaration { - let interfaceDeclaration = this.astFactory.createInterfaceDeclaration( + convertInterfaceDeclaration(statement: ts.InterfaceDeclaration, computeDefinitions: boolean = true): Declaration { + return this.astFactory.createInterfaceDeclaration( this.astFactory.createIdentifierDeclarationAsNameEntity(statement.name.getText()), this.convertMembersToInterfaceMemberDeclarations(statement.members), this.convertTypeParams(statement.typeParameters), @@ -734,8 +710,6 @@ export class AstConverter { computeDefinitions ? this.convertDefinitions(ts.SyntaxKind.InterfaceDeclaration, statement.name) : [], this.exportContext.getUID(statement) ); - - return interfaceDeclaration; } convertTopLevelStatement(statement: ts.Node): Array { @@ -814,7 +788,7 @@ export class AstConverter { res.push(this.astFactory.createImportEqualsDeclaration( statement.name.getText(), - moduleReferenceDeclaration as ModuleReferenceDeclaration, + moduleReferenceDeclaration, uid )); } else { @@ -870,7 +844,7 @@ export class AstConverter { let definitionsInfoDeclarations: Array = []; if (definitionInfos) { definitionsInfoDeclarations = definitionInfos.map(definitionInfo => { - return this.astFactory.createDefinitionInfoDeclaration(definitionInfo.fileName); + return this.astFactory.createDefinitionInfoDeclaration(definitionInfo.getFilename()); }); } diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index c4c8c5af5..6711e6e2c 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -1,53 +1,34 @@ import * as declarations from "declarations"; import { - CallSignatureDeclaration, - ClassDeclaration, - ClassLikeDeclaration, - ConstructorDeclaration, - Declaration, DefinitionInfoDeclaration, - EnumDeclaration, EnumTokenDeclaration, - ExportAssignmentDeclaration, Expression, FunctionDeclaration, - FunctionTypeDeclaration, HeritageClauseDeclaration, - IdentifierEntity, - ImportEqualsDeclaration, - IndexSignatureDeclaration, - InterfaceDeclaration, - IntersectionTypeDeclaration, + IdentifierDeclaration, MemberDeclaration, - MethodSignatureDeclaration, ModifierDeclaration, ModuleDeclaration, - ModuleReferenceDeclaration, NameEntity, - ObjectLiteral, ParameterDeclaration, - ParameterValue, - PropertyDeclaration, ProtoMessage, - QualifierEntity, + TypeDeclaration, ReferenceEntity, SourceFileDeclaration, SourceSet, - StringLiteralDeclaration, - ThisTypeDeclaration, - TupleDeclaration, - TypeAliasDeclaration, - TypeDeclaration, + Declaration, + TypeParamReferenceDeclaration, TypeParameter, - UnionTypeDeclatation, - VariableDeclaration + TypeReferenceDeclaration } from "./ast"; import {createLogger} from "../Logger"; +import {TypeReferenceDeclarationProto} from "declarations"; +import {HeritageClauseDeclarationProto} from "declarations"; export class AstFactory implements AstFactory { private log = createLogger("AstFactory"); - createCallSignatureDeclaration(parameters: Array, type: ParameterValue, typeParams: Array): CallSignatureDeclaration { + createCallSignatureDeclaration(parameters: Array, type: TypeDeclaration, typeParams: Array): MemberDeclaration { let callSignature = new declarations.CallSignatureDeclarationProto(); callSignature.setParametersList(parameters); callSignature.setType(type); @@ -58,7 +39,7 @@ export class AstFactory implements AstFactory { return memberProto; } - createClassDeclaration(name: NameEntity, members: Array, typeParams: Array, parentEntities: Array, modifiers: Array, uid: string): ClassDeclaration { + createClassDeclaration(name: NameEntity, members: Array, typeParams: Array, parentEntities: Array, modifiers: Array, uid: string): Declaration { let classDeclaration = new declarations.ClassDeclarationProto(); classDeclaration.setName(name); classDeclaration.setModifiersList(modifiers); @@ -72,15 +53,15 @@ export class AstFactory implements AstFactory { return topLevelDeclaration; } - createConstructorDeclaration(parameters: Array, typeParams: Array, modifiers: Array): ConstructorDeclaration { - let constuctorDeclaration = new declarations.ConstructorDeclarationProto(); + createConstructorDeclaration(parameters: Array, typeParams: Array, modifiers: Array): MemberDeclaration { + let constructorDeclaration = new declarations.ConstructorDeclarationProto(); - constuctorDeclaration.setParametersList(parameters); - constuctorDeclaration.setTypeparametersList(typeParams); - constuctorDeclaration.setModifiersList(modifiers); + constructorDeclaration.setParametersList(parameters); + constructorDeclaration.setTypeparametersList(typeParams); + constructorDeclaration.setModifiersList(modifiers); let memberProto = new declarations.MemberDeclarationProto(); - memberProto.setConstructordeclaration(constuctorDeclaration); + memberProto.setConstructordeclaration(constructorDeclaration); return memberProto; } @@ -90,7 +71,7 @@ export class AstFactory implements AstFactory { return definition; } - createEnumDeclaration(name: string, values: Array): EnumDeclaration { + createEnumDeclaration(name: string, values: Array): Declaration { let enumDeclaration = new declarations.EnumDeclarationProto(); enumDeclaration.setName(name); enumDeclaration.setValuesList(values); @@ -107,7 +88,7 @@ export class AstFactory implements AstFactory { return enumToken; } - createExportAssignmentDeclaration(name: string, isExportEquals: boolean): ExportAssignmentDeclaration { + createExportAssignmentDeclaration(name: string, isExportEquals: boolean): Declaration { let exportAssignment = new declarations.ExportAssignmentDeclarationProto(); exportAssignment.setName(name); exportAssignment.setIsexportequals(isExportEquals); @@ -117,7 +98,7 @@ export class AstFactory implements AstFactory { return topLevelDeclaration; } - createExpression(kind: TypeDeclaration, meta: string): Expression { + createExpression(kind: TypeReferenceDeclarationProto, meta: string): Expression { let expression = new declarations.ExpressionDeclarationProto(); expression.setKind(kind); expression.setMeta(meta); @@ -126,7 +107,7 @@ export class AstFactory implements AstFactory { } - private createFunctionDeclaration(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, uid: String): ProtoMessage { + private createFunctionDeclaration(name: string, parameters: Array, type: TypeDeclaration, typeParams: Array, modifiers: Array, uid: string): FunctionDeclaration { let functionDeclaration = new declarations.FunctionDeclarationProto(); functionDeclaration.setName(name); functionDeclaration.setParametersList(parameters); @@ -137,7 +118,7 @@ export class AstFactory implements AstFactory { return functionDeclaration } - createFunctionDeclarationAsMember(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, uid: String): FunctionDeclaration { + createFunctionDeclarationAsMember(name: string, parameters: Array, type: TypeDeclaration, typeParams: Array, modifiers: Array, uid: string): MemberDeclaration { let functionDeclaration = this.createFunctionDeclaration(name, parameters, type, typeParams, modifiers, uid); let memberProto = new declarations.MemberDeclarationProto(); @@ -145,7 +126,7 @@ export class AstFactory implements AstFactory { return memberProto; } - createFunctionDeclarationAsTopLevel(name: string, parameters: Array, type: ParameterValue, typeParams: Array, modifiers: Array, uid: String): FunctionDeclaration { + createFunctionDeclarationAsTopLevel(name: string, parameters: Array, type: TypeDeclaration, typeParams: Array, modifiers: Array, uid: string): Declaration { let functionDeclaration = this.createFunctionDeclaration(name, parameters, type, typeParams, modifiers, uid); let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); @@ -153,7 +134,7 @@ export class AstFactory implements AstFactory { return topLevelDeclaration; } - createFunctionTypeDeclaration(parameters: Array, type: ParameterValue): FunctionTypeDeclaration { + createFunctionTypeDeclaration(parameters: Array, type: TypeDeclaration): TypeDeclaration { let functionType = new declarations.FunctionDeclarationProto(); functionType.setParametersList(parameters); functionType.setType(type); @@ -163,7 +144,7 @@ export class AstFactory implements AstFactory { return paramValueDeclaration; } - createHeritageClauseDeclaration(name: NameEntity, typeArguments: Array, extending: boolean, typeReference: ReferenceEntity | null): HeritageClauseDeclaration { + createHeritageClauseDeclaration(name: NameEntity, typeArguments: Array, extending: boolean, typeReference: ReferenceEntity | null): HeritageClauseDeclaration { let heritageClauseDeclaration = new declarations.HeritageClauseDeclarationProto(); heritageClauseDeclaration.setName(name); @@ -177,7 +158,7 @@ export class AstFactory implements AstFactory { return heritageClauseDeclaration; } - createIdentifierDeclarationAsNameEntity(value: string): IdentifierEntity { + createIdentifierDeclarationAsNameEntity(value: string): NameEntity { let identifierProto = new declarations.IdentifierDeclarationProto(); identifierProto.setValue(value); let nameEntity = new declarations.NameDeclarationProto(); @@ -185,13 +166,13 @@ export class AstFactory implements AstFactory { return nameEntity; } - createIdentifierDeclaration(value: string): IdentifierEntity { + createIdentifierDeclaration(value: string): IdentifierDeclaration { let identifierProto = new declarations.IdentifierDeclarationProto(); identifierProto.setValue(value); return identifierProto; } - createImportEqualsDeclaration(name: string, moduleReference: ModuleReferenceDeclaration, uid: string): ImportEqualsDeclaration { + createImportEqualsDeclaration(name: string, moduleReference: NameEntity, uid: string): Declaration { let importEqualsDeclaration = new declarations.ImportEqualsDeclarationProto(); importEqualsDeclaration.setName(name); importEqualsDeclaration.setModulereference(moduleReference); @@ -202,7 +183,7 @@ export class AstFactory implements AstFactory { return topLevelDeclaration; } - createIndexSignatureDeclaration(indexTypes: Array, returnType: ParameterValue): IndexSignatureDeclaration { + createIndexSignatureDeclaration(indexTypes: Array, returnType: TypeDeclaration): MemberDeclaration { let indexSignatureDeclaration = new declarations.IndexSignatureDeclarationProto(); indexSignatureDeclaration.setIndextypesList(indexTypes); indexSignatureDeclaration.setReturntype(returnType); @@ -212,7 +193,7 @@ export class AstFactory implements AstFactory { return memberEntity; } - createInterfaceDeclaration(name: NameEntity, members: Array, typeParams: Array, parentEntities: Array, definitionsInfo: Array, uid: String): InterfaceDeclaration { + createInterfaceDeclaration(name: NameEntity, members: Array, typeParams: Array, parentEntities: Array, definitionsInfo: Array, uid: string): Declaration { let interfaceDeclaration = new declarations.InterfaceDeclarationProto(); interfaceDeclaration.setName(name); interfaceDeclaration.setUid(uid); @@ -226,7 +207,7 @@ export class AstFactory implements AstFactory { return topLevelDeclaration; } - createIntersectionTypeDeclaration(params: Array): IntersectionTypeDeclaration { + createIntersectionTypeDeclaration(params: Array): TypeDeclaration { let intersection = new declarations.IntersectionTypeDeclarationProto(); intersection.setParamsList(params); @@ -235,19 +216,19 @@ export class AstFactory implements AstFactory { return paramValueDeclaration; } - createMethodDeclaration(name: string, parameters: Array, type: ParameterValue, typeParams: Array): FunctionDeclaration { + createMethodDeclaration(name: string, parameters: Array, type: TypeDeclaration, typeParams: Array): MemberDeclaration { let methodDeclaration = new declarations.FunctionDeclarationProto(); - methodDeclaration.seetName(name); + methodDeclaration.setName(name); methodDeclaration.setParametersList(parameters); methodDeclaration.setType(type); - methodDeclaration.setTypeparamsList(typeParams); + methodDeclaration.setTypeparametersList(typeParams); let memberProto = new declarations.MemberDeclarationProto(); - memberProto.setFunctionDeclarataion(memberProto); + memberProto.setFunctiondeclaration(methodDeclaration); return memberProto; } - createMethodSignatureDeclaration(name: string, parameters: Array, type: ParameterValue, typeParams: Array, optional: boolean, modifiers: Array): MethodSignatureDeclaration { + createMethodSignatureDeclaration(name: string, parameters: Array, type: TypeDeclaration, typeParams: Array, optional: boolean, modifiers: Array): MemberDeclaration { let methodSignature = new declarations.MethodSignatureDeclarationProto(); methodSignature.setName(name); methodSignature.setParametersList(parameters); @@ -279,15 +260,15 @@ export class AstFactory implements AstFactory { return moduleDeclaration; } - createModuleDeclarationAsTopLevel(packageName: NameEntity, toplevels: Declaration[], modifiers: Array, definitionsInfo: Array, uid: string, resourceName: string, root: boolean): ModuleDeclaration { - let module = this.createModuleDeclaration(packageName, toplevels, modifiers, definitionsInfo, uid, resourceName, root); + createModuleDeclarationAsTopLevel(packageName: NameEntity, topLevels: Declaration[], modifiers: Array, definitionsInfo: Array, uid: string, resourceName: string, root: boolean): Declaration { + let module = this.createModuleDeclaration(packageName, topLevels, modifiers, definitionsInfo, uid, resourceName, root); let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); topLevelDeclaration.setModuledeclaration(module); return topLevelDeclaration; } - createObjectLiteral(members: Array): ObjectLiteral { + createObjectLiteral(members: Array): TypeDeclaration { let objectLiteral = new declarations.ObjectLiteralDeclarationProto(); objectLiteral.setMembersList(members); @@ -296,7 +277,7 @@ export class AstFactory implements AstFactory { return paramValueDeclaration; } - createParameterDeclaration(name: string, type: ParameterValue, initializer: Expression | null, vararg: boolean, optional: boolean): ParameterDeclaration { + createParameterDeclaration(name: string, type: TypeDeclaration, initializer: Expression | null, vararg: boolean, optional: boolean): ParameterDeclaration { let parameterDeclaration = new declarations.ParameterDeclarationProto(); parameterDeclaration.setName(name); parameterDeclaration.setType(type); @@ -308,7 +289,7 @@ export class AstFactory implements AstFactory { return parameterDeclaration; } - createQualifiedNameDeclaration(left: NameEntity, right: IdentifierEntity): QualifierEntity { + createQualifiedNameDeclaration(left: NameEntity, right: IdentifierDeclaration): NameEntity { let qualifier = new declarations.QualifierDeclarationProto(); qualifier.setLeft(left); qualifier.setRight(right); @@ -324,11 +305,13 @@ export class AstFactory implements AstFactory { return reference; } - createSourceFileDeclaration(fileName: string, root: ModuleDeclaration | null, referencedFiles: Array): SourceFileDeclaration { + createSourceFileDeclaration(fileName: string, root: ModuleDeclaration | null, referencedFiles: Array): SourceFileDeclaration { let sourceFile = new declarations.SourceFileDeclarationProto(); sourceFile.setFilename(fileName); sourceFile.setReferencedfilesList([]); - sourceFile.setRoot(root); + if (root) { + sourceFile.setRoot(root); + } return sourceFile; } @@ -339,7 +322,7 @@ export class AstFactory implements AstFactory { return sourceSet; } - createStringLiteralDeclaration(token: string): StringLiteralDeclaration { + createStringLiteralDeclaration(token: string): TypeDeclaration { let stringLiteral = new declarations.StringLiteralDeclarationProto(); stringLiteral.setToken(token); @@ -348,13 +331,13 @@ export class AstFactory implements AstFactory { return paramValueDeclaration; } - createThisTypeDeclaration(): ThisTypeDeclaration { + createThisTypeDeclaration(): TypeDeclaration { let parameterValueDeclaration = new declarations.ParameterValueDeclarationProto(); parameterValueDeclaration.setThistype(new declarations.ThisTypeDeclarationProto()); return parameterValueDeclaration; } - createTupleDeclaration(params: Array): TupleDeclaration { + createTupleDeclaration(params: Array): TypeDeclaration { let tupleDeclaration = new declarations.TupleDeclarationProto(); tupleDeclaration.setParamsList(params); @@ -363,7 +346,7 @@ export class AstFactory implements AstFactory { return paramValueDeclaration; } - createTypeAliasDeclaration(aliasName: NameEntity, typeParams: Array, typeReference: ParameterValue, uid: String): TypeAliasDeclaration { + createTypeAliasDeclaration(aliasName: NameEntity, typeParams: Array, typeReference: TypeDeclaration, uid: string): Declaration { let typeAlias = new declarations.TypeAliasDeclarationProto(); typeAlias.setAliasname(aliasName); typeAlias.setTypeparametersList(typeParams); @@ -375,7 +358,7 @@ export class AstFactory implements AstFactory { return topLevelDeclaration; } - createTypeReferenceDeclaration(value: NameEntity, params: Array, typeReference: ReferenceEntity | null = null): TypeDeclaration { + createTypeReferenceDeclaration(value: NameEntity, params: Array, typeReference: ReferenceEntity | null = null): TypeReferenceDeclaration { let typeDeclaration = new declarations.TypeReferenceDeclarationProto(); typeDeclaration.setValue(value); typeDeclaration.setParamsList(params); @@ -387,7 +370,7 @@ export class AstFactory implements AstFactory { return typeDeclaration; } - createTypeParamReferenceDeclaration(value: NameEntity): TypeDeclaration { + createTypeParamReferenceDeclaration(value: NameEntity): TypeParamReferenceDeclaration { let typeDeclaration = new declarations.TypeParamReferenceDeclarationProto(); typeDeclaration.setValue(value); return typeDeclaration; @@ -399,21 +382,23 @@ export class AstFactory implements AstFactory { return paramValueDeclaration; } - createTypeReferenceDeclarationAsParamValue(value: NameEntity, params: Array, typeReference: ReferenceEntity | null): ParameterValue { + createTypeReferenceDeclarationAsParamValue(value: NameEntity, params: Array, typeReference: ReferenceEntity | null): TypeDeclaration { let paramValueDeclaration = new declarations.ParameterValueDeclarationProto(); paramValueDeclaration.setTypereferencedeclaration(this.createTypeReferenceDeclaration(value, params, typeReference)); return paramValueDeclaration; } - createTypeParam(name: NameEntity, constraints: Array, defaultValue: ParameterValue | null): TypeParameter { + createTypeParam(name: NameEntity, constraints: Array, defaultValue: TypeDeclaration | null): TypeParameter { let typeParam = new declarations.TypeParameterDeclarationProto(); typeParam.setName(name); typeParam.setConstraintsList(constraints); - typeParam.setDefaultvalue(defaultValue); + if (defaultValue) { + typeParam.setDefaultvalue(defaultValue); + } return typeParam; } - createUnionTypeDeclaration(params: Array): UnionTypeDeclatation { + createUnionTypeDeclaration(params: Array): TypeDeclaration { let unionTypeDeclaration = new declarations.UnionTypeDeclarationProto(); unionTypeDeclaration.setParamsList(params); @@ -422,7 +407,7 @@ export class AstFactory implements AstFactory { return paramValueDeclaration; } - declareProperty(name: string, type: ParameterValue, typeParams: Array, optional: boolean, modifiers: Array): PropertyDeclaration { + declareProperty(name: string, type: TypeDeclaration, typeParams: Array, optional: boolean, modifiers: Array): MemberDeclaration { let propertyDeclaration = new declarations.PropertyDeclarationProto(); propertyDeclaration.setName(name); propertyDeclaration.setType(type); @@ -435,7 +420,7 @@ export class AstFactory implements AstFactory { return memberProto; } - declareVariable(name: string, type: ParameterValue, modifiers: Array, uid: String): VariableDeclaration { + declareVariable(name: string, type: TypeDeclaration, modifiers: Array, uid: string): Declaration { let variableDeclaration = new declarations.VariableDeclarationProto(); variableDeclaration.setName(name); variableDeclaration.setType(type); diff --git a/typescript/ts-converter/src/ast/ast.ts b/typescript/ts-converter/src/ast/ast.ts index d02c7dbfa..ae8681f6d 100644 --- a/typescript/ts-converter/src/ast/ast.ts +++ b/typescript/ts-converter/src/ast/ast.ts @@ -1,163 +1,63 @@ -export declare interface ProtoMessage { - serializeBinary(): Int8Array; -} - -export declare interface NameEntityProto extends ProtoMessage {} -export declare interface IdentifierEntityProto extends NameEntityProto { - setValue(value: string): void; -} -export declare interface QualifierEntityProto extends NameEntityProto { - setRight(right: IdentifierEntityProto): void; - setLeft(left: NameEntityProto): void; -} - -declare interface AstNode { -} - - -export declare class Declaration implements AstNode, ProtoMessage { - serializeBinary(): Int8Array -} - -export declare interface ReferenceEntity { - uid: String; -} - -export declare interface DefinitionInfoDeclaration extends AstNode { - fileName: string; -} - -export declare interface TupleDeclaration extends ParameterValue {} - -export declare interface NameEntity extends Declaration { - hasIdentifier(): boolean; - hasQualifier(): boolean; - getQualifier(): QualifierEntity; - getIdentifier(): IdentifierEntity; -} - -export declare interface IdentifierEntity extends ParameterValue, ModuleReferenceDeclaration, NameEntity {} -export declare interface QualifierEntity extends NameEntity { - getLeft(): NameEntity, - getRight(): IdentifierEntity -} - -export declare interface ThisTypeDeclaration extends Declaration {} -export declare interface ModuleReferenceDeclaration extends Declaration {} - -export declare interface ImportEqualsDeclaration extends Declaration { - name: string -} - -export declare interface EnumDeclaration extends ParameterValue { - values: Array -} - -export declare interface EnumTokenDeclaration extends Declaration { - value: string; - meta: string; -} - -export declare interface ExportAssignmentDeclaration extends Declaration { - name: string; -} - -export declare interface IntersectionTypeDeclaration extends Declaration {} -export declare interface UnionTypeDeclatation extends Declaration {} -export declare interface HeritageClauseDeclaration extends Declaration { - name: NameEntity, - typeArguments: Array, - extending: boolean, - typeReference: ReferenceEntity | null -} -export declare interface TypeAliasDeclaration extends Declaration {} -export declare interface IndexSignatureDeclaration extends ParameterValue {} -export declare interface StringLiteralDeclaration - extends ParameterValue {} - -export declare interface CallSignatureDeclaration extends MemberDeclaration {} -export declare interface ConstructorDeclaration extends MemberDeclaration {} - -export declare interface ModifierDeclaration extends Declaration { - token: string; -} - -export declare interface MemberDeclaration extends Declaration { -} - -export declare class ClassDeclaration implements Declaration { - name: String; - serializeBinary(): Int8Array; -} - -export declare class InterfaceDeclaration implements Declaration { - serializeBinary(): Int8Array; -} -export declare class MethodSignatureDeclaration implements Declaration { - serializeBinary(): Int8Array; -} - -export declare class ObjectLiteral implements ParameterValue { - serializeBinary(): Int8Array; -} - -export declare class VariableDeclaration implements Declaration { - name: String; - type: TypeDeclaration; - serializeBinary(): Int8Array; -} - -export declare class PropertyDeclaration implements MemberDeclaration { - name: string; - type: TypeDeclaration; - immmutable: boolean; - serializeBinary(): Int8Array; -} - -export declare class Expression implements Declaration { - kind: TypeDeclaration; - meta: String; - serializeBinary(): Int8Array; -} - -export declare interface ParameterValue extends Declaration {} - -export declare class ParameterDeclaration extends Declaration { - name: String; - type: ParameterValue; -} - -export declare class ModuleDeclaration implements Declaration { - declarations: Declaration[]; - serializeBinary(): Int8Array; -} - -export declare class SourceFileDeclaration implements AstNode { - declarations: Declaration[] -} - -export declare class SourceSet implements Declaration { - serializeBinary(): Int8Array; -} - -export declare class SourceBundle implements Declaration { - serializeBinary(): Int8Array; -} - -export declare class TypeParameter { - name: String; -} - -export type ClassLikeDeclaration = ClassDeclaration | InterfaceDeclaration - -export declare class TypeDeclaration implements ParameterValue { - serializeBinary(): Int8Array; -} - -export declare class FunctionDeclaration implements MemberDeclaration { - serializeBinary(): Int8Array; -} - -export declare class FunctionTypeDeclaration implements ParameterValue { - serializeBinary(): Int8Array; -} +import { + CallSignatureDeclarationProto, + ClassDeclarationProto, + ConstructorDeclarationProto, + DefinitionInfoDeclarationProto, + EnumDeclarationProto, + EnumTokenDeclarationProto, + ExpressionDeclarationProto, + FunctionDeclarationProto, + HeritageClauseDeclarationProto, + IdentifierDeclarationProto, + ImportEqualsDeclarationProto, + IndexSignatureDeclarationProto, + InterfaceDeclarationProto, + MemberDeclarationProto, + ModifierDeclarationProto, + ModuleDeclarationProto, + NameDeclarationProto, + ParameterDeclarationProto, + ParameterValueDeclarationProto, + PropertyDeclarationProto, + ReferenceDeclarationProto, + SourceBundleDeclarationProto, + SourceFileDeclarationProto, + SourceSetDeclarationProto, + TopLevelDeclarationProto, + TypeAliasDeclarationProto, + TypeParameterDeclarationProto, + TypeParamReferenceDeclarationProto, + TypeReferenceDeclarationProto, + VariableDeclarationProto +} from "declarations"; + +export type CallSignatureDeclaration = CallSignatureDeclarationProto; +export type ClassDeclaration = ClassDeclarationProto; +export type ConstructorDeclaration = ConstructorDeclarationProto; +export type DefinitionInfoDeclaration = DefinitionInfoDeclarationProto; +export type EnumDeclaration = EnumDeclarationProto; +export type EnumTokenDeclaration = EnumTokenDeclarationProto; +export type Expression = ExpressionDeclarationProto; +export type FunctionDeclaration = FunctionDeclarationProto; +export type HeritageClauseDeclaration = HeritageClauseDeclarationProto; +export type IdentifierDeclaration = IdentifierDeclarationProto; +export type ImportEqualsDeclaration = ImportEqualsDeclarationProto; +export type IndexSignatureDeclaration = IndexSignatureDeclarationProto; +export type InterfaceDeclaration = InterfaceDeclarationProto; +export type MemberDeclaration = MemberDeclarationProto; +export type ModifierDeclaration = ModifierDeclarationProto; +export type ModuleDeclaration = ModuleDeclarationProto; +export type NameEntity = NameDeclarationProto; +export type ParameterDeclaration = ParameterDeclarationProto; +export type TypeDeclaration = ParameterValueDeclarationProto; +export type PropertyDeclaration = PropertyDeclarationProto; +export type ReferenceEntity = ReferenceDeclarationProto; +export type SourceBundle = SourceBundleDeclarationProto; +export type SourceFileDeclaration = SourceFileDeclarationProto; +export type SourceSet = SourceSetDeclarationProto; +export type Declaration = TopLevelDeclarationProto; +export type TypeAliasDeclaration = TypeAliasDeclarationProto; +export type TypeParameter = TypeParameterDeclarationProto; +export type TypeParamReferenceDeclaration = TypeParamReferenceDeclarationProto; +export type TypeReferenceDeclaration = TypeReferenceDeclarationProto; +export type VariableDeclaration = VariableDeclarationProto; \ No newline at end of file diff --git a/typescript/ts-converter/src/toNameEntity.ts b/typescript/ts-converter/src/toNameEntity.ts deleted file mode 100644 index daeb9362a..000000000 --- a/typescript/ts-converter/src/toNameEntity.ts +++ /dev/null @@ -1,24 +0,0 @@ -import {NameEntity} from "./ast/ast"; -import {AstFactory} from "./ast/AstFactory"; - -const astFactory = new AstFactory(); - -export function toNameEntity(name: string): NameEntity { - if (name == "") { - return astFactory.createIdentifierDeclarationAsNameEntity(name) - } else { - return name.split(".") - .map(it => astFactory.createIdentifierDeclarationAsNameEntity(it)) - .reduce((acc, identifier) => { - return concatenate(identifier, acc); - }) - } -} - -function concatenate(a: NameEntity, b: NameEntity) { - if (b.hasIdentifier()) { - return astFactory.createQualifiedNameDeclaration(a, b) - } else if (b.hasQualifier()) { - return concatenate(concatenate(a, b.getQualifier().getLeft()), b.getQualifier().getRight()); - } -} diff --git a/typescript/ts-converter/tsconfig.json b/typescript/ts-converter/tsconfig.json index c861718d1..c293559b5 100644 --- a/typescript/ts-converter/tsconfig.json +++ b/typescript/ts-converter/tsconfig.json @@ -16,7 +16,8 @@ ], "paths": { "typescript-services-api": ["./build/package/node_modules/typescript/lib/typescriptServices.js"], - "declarations": ["../ts-model-proto/build/generated/source/proto/main/js/Declarations_pb.js"] + "declarations": ["../ts-model-proto/build/generated/source/proto/main/js/Declarations_pb"], + "google-protobuf": ["./build/package/node_modules/google-protobuf"] } }, "include": [ diff --git a/typescript/ts-converter/webpack.config.js b/typescript/ts-converter/webpack.config.js index 6dabc3765..dc1e80a14 100644 --- a/typescript/ts-converter/webpack.config.js +++ b/typescript/ts-converter/webpack.config.js @@ -13,7 +13,7 @@ module.exports = { }, resolve: { alias: { - "declarations": path.resolve("../ts-model-proto/build/generated/source/proto/main/js/Declarations_pb.js"), + "declarations": path.resolve("../ts-model-proto/build/generated/source/proto/main/js/Declarations_pb"), "google-protobuf": path.resolve("./build/package/node_modules/google-protobuf"), "typescript-services-api": path.resolve("./build/package/node_modules/typescript/lib/typescriptServices.js") } diff --git a/typescript/ts-model-proto/build.gradle b/typescript/ts-model-proto/build.gradle index a3e65add1..6e507467a 100644 --- a/typescript/ts-model-proto/build.gradle +++ b/typescript/ts-model-proto/build.gradle @@ -1,6 +1,41 @@ plugins { id "java" id "com.google.protobuf" + id "com.moowork.node" +} + +def targetMainDir = "${project.buildDir}/generated/source/proto/main" + +def nodeModulesPath = "${project.buildDir}/node" + +node { + workDir = gradle.nodeWorkingDir + + version = gradle.nodeVersion + npmVersion = gradle.npmVersion + yarnVersion = gradle.yarnVersion + + nodeModulesDir = file(nodeModulesPath) + download = true +} + +task addProtocGenTs(type: YarnTask) { + outputs.dir(nodeModulesPath) + args = ['add', 'ts-protoc-gen'] +} + +task moveGeneratedTS() { + doLast { + def tsDir = file("$targetMainDir/ts") + + if (tsDir.exists() && tsDir.isDirectory()) { + tsDir.eachFile { file -> + file.renameTo("$targetMainDir/js/${file.getName()}") + } + + tsDir.delete() + } + } } dependencies { @@ -9,7 +44,7 @@ dependencies { sourceSets { generated { - java.srcDir("${project.buildDir}/generated/source/proto/main/java") + java.srcDir("$targetMainDir/java") } main { @@ -18,23 +53,43 @@ sourceSets { } java { - srcDirs = ["${project.buildDir}/generated/source/proto/main/java"] + srcDirs = ["$targetMainDir/java"] } } } protobuf { - protoc { - artifact = "com.google.protobuf:protoc:${gradle.protobufImplementationVersion}" + plugins { + ts { + path = file(nodeModulesPath).absolutePath + "/node_modules/ts-protoc-gen/bin/protoc-gen-ts" + + if (System.properties['os.name'].toLowerCase().contains('windows')) { + path = path + ".cmd" + } + } } + generateProtoTasks { all().each { task -> + if(task.getName() == 'generateProto') { + task.dependsOn(addProtocGenTs) + task.finalizedBy(moveGeneratedTS) + } + task.builtins { js { option "import_style=commonjs" option "binary" } } + + task.plugins { + ts { } + } } } + + protoc { + artifact = "com.google.protobuf:protoc:${gradle.protobufImplementationVersion}" + } } \ No newline at end of file From 249ae6e98722102ed1bd36fb7839cb49ae60263a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Nov 2019 13:23:52 +0100 Subject: [PATCH 085/172] Fix scopes used for resolving references. --- .../test/data/javascript/function/nested.d.kt | 24 +++++++ .../test/data/javascript/function/nested.d.ts | 23 +++++++ .../dukat/js/type/analysis/expression.kt | 14 ++-- .../dukat/js/type/analysis/introduceTypes.kt | 69 ++++++++++--------- .../dukat/js/type/constraint/Constraint.kt | 4 +- .../composite/CompositeConstraint.kt | 6 +- .../composite/UnionTypeConstraint.kt | 4 +- .../immutable/resolved/ResolvedConstraint.kt | 3 +- .../constraint/properties/ClassConstraint.kt | 8 +-- .../properties/FunctionConstraint.kt | 12 ++-- .../constraint/properties/ObjectConstraint.kt | 15 ++-- .../properties/PropertyOwnerConstraint.kt | 2 +- .../PropertyOwnerReferenceConstraint.kt | 6 +- .../reference/ReferenceConstraint.kt | 38 ++++++---- .../reference/call/CallArgumentConstraint.kt | 5 +- .../reference/call/CallResultConstraint.kt | 11 +-- .../GeneralExportResolver.kt | 2 +- .../js/type/property_owner/PropertyOwner.kt | 23 +------ .../dukat/js/type/property_owner/Scope.kt | 4 +- 19 files changed, 158 insertions(+), 115 deletions(-) create mode 100644 compiler/test/data/javascript/function/nested.d.kt create mode 100644 compiler/test/data/javascript/function/nested.d.ts diff --git a/compiler/test/data/javascript/function/nested.d.kt b/compiler/test/data/javascript/function/nested.d.kt new file mode 100644 index 000000000..73c84bd0c --- /dev/null +++ b/compiler/test/data/javascript/function/nested.d.kt @@ -0,0 +1,24 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun numFun(): Number + +external var value: String + +external fun bar(): String + +external fun strFun(): String \ No newline at end of file diff --git a/compiler/test/data/javascript/function/nested.d.ts b/compiler/test/data/javascript/function/nested.d.ts new file mode 100644 index 000000000..4c4f96f5b --- /dev/null +++ b/compiler/test/data/javascript/function/nested.d.ts @@ -0,0 +1,23 @@ + +function numFun() { + var x = 3 + + function foo() { + return x + } + + return foo() +} + + +var value = "text" + +function bar() { + return value +} + +function strFun() { + var value = 3 + + return bar() +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 06c29a305..36e351702 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -123,6 +123,7 @@ fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: P } return CallResultConstraint( + owner, callTargetConstraints ) } @@ -134,37 +135,38 @@ fun NewExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: Pa arguments.map { it.calculateConstraints(owner, path) } return ObjectConstraint( + owner = owner, instantiatedClass = classConstraints as ClassConstraint ) } -fun ObjectLiteralExpressionDeclaration.calculateConstraints(path: PathWalker) : ObjectConstraint { - val obj = ObjectConstraint() +fun ObjectLiteralExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : ObjectConstraint { + val obj = ObjectConstraint(owner) members.forEach { it.addTo(obj, path) } return obj } -fun LiteralExpressionDeclaration.calculateConstraints(path: PathWalker) : Constraint { +fun LiteralExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { return when (this) { is StringLiteralExpressionDeclaration -> StringTypeConstraint is NumericLiteralExpressionDeclaration -> NumberTypeConstraint is BigIntLiteralExpressionDeclaration -> BigIntTypeConstraint is BooleanLiteralExpressionDeclaration -> BooleanTypeConstraint - is ObjectLiteralExpressionDeclaration -> this.calculateConstraints(path) + is ObjectLiteralExpressionDeclaration -> this.calculateConstraints(owner, path) else -> raiseConcern("Unexpected literal expression type <${this::class}>") { CompositeConstraint(NoTypeConstraint) } } } fun ExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { return when (this) { - is IdentifierExpressionDeclaration -> owner[this] ?: ReferenceConstraint(this.identifier) + is IdentifierExpressionDeclaration -> owner[this] ?: ReferenceConstraint(this.identifier, owner) is PropertyAccessExpressionDeclaration -> owner[this, path] ?: CompositeConstraint() //TODO replace this with a reference constraint (of some sort) is BinaryExpressionDeclaration -> this.calculateConstraints(owner, path) is UnaryExpressionDeclaration -> this.calculateConstraints(owner, path) is TypeOfExpressionDeclaration -> this.calculateConstraints(owner, path) is CallExpressionDeclaration -> this.calculateConstraints(owner, path) is NewExpressionDeclaration -> this.calculateConstraints(owner, path) - is LiteralExpressionDeclaration -> this.calculateConstraints(path) + is LiteralExpressionDeclaration -> this.calculateConstraints(owner, path) else -> CompositeConstraint(NoTypeConstraint) } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index 95c678379..4c1560740 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -31,6 +31,29 @@ import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.WhileStatementDeclaration +fun List.pack() : FunctionConstraint { + return if (size == 1) { + this[0] + } else { + val parameters = mutableListOf>>() + + forEach { + it.parameterConstraints.forEachIndexed { index, (name, constraint) -> + if (parameters.size <= index) { + parameters.add(index, name to mutableListOf()) + } + + parameters[index].second.add(constraint) + } + } + + FunctionConstraint( + returnConstraints = UnionTypeConstraint(map { it.returnConstraints }), + parameterConstraints = parameters.map { (name, constraints) -> name to UnionTypeConstraint(constraints) } + ) + } +} + fun FunctionDeclaration.addTo(owner: PropertyOwner) { if (this.body != null) { val pathWalker = PathWalker() @@ -38,7 +61,7 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) { val versions = mutableListOf() do { - val functionScope = Scope() + val functionScope = Scope(owner) val parameterConstraints = MutableList(parameters.size) { i -> // Store constraints of parameters in scope, @@ -56,26 +79,7 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) { )) } while (pathWalker.startNextPath()) - owner[name] = if (versions.size == 1) { - versions[0] - } else { - val parameters = mutableListOf>>() - - versions.forEach { - it.parameterConstraints.forEachIndexed { index, (name, constraint) -> - if (parameters.size <= index) { - parameters.add(index, name to mutableListOf()) - } - - parameters[index].second.add(constraint) - } - } - - FunctionConstraint( - returnConstraints = UnionTypeConstraint(versions.map { it.returnConstraints }), - parameterConstraints = parameters.map { (name, constraints) -> name to UnionTypeConstraint(constraints) } - ) - } + owner[name] = versions.pack() } } @@ -120,7 +124,7 @@ fun MemberDeclaration.addToClass(owner: ClassConstraint, path: PathWalker) { fun ClassDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { val className = name // Needed for smart cast if(className is IdentifierEntity) { - val classConstraint = ClassConstraint() + val classConstraint = ClassConstraint(owner) members.forEach { it.addToClass(classConstraint, path) } @@ -165,23 +169,21 @@ fun ReturnStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: } fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { - var returnTypeConstraints: Constraint? = null - when (this) { is FunctionDeclaration -> this.addTo(owner) is ClassDeclaration -> this.addTo(owner, path) is VariableDeclaration -> this.addTo(owner, path) - is IfStatementDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) - is WhileStatementDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) + is IfStatementDeclaration -> return this.calculateConstraints(owner, path) + is WhileStatementDeclaration -> return this.calculateConstraints(owner, path) is ExpressionStatementDeclaration -> this.calculateConstraints(owner, path) - is BlockDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) - is ReturnStatementDeclaration -> returnTypeConstraints = this.calculateConstraints(owner, path) + is BlockDeclaration -> return this.calculateConstraints(owner, path) + is ReturnStatementDeclaration -> return this.calculateConstraints(owner, path) is InterfaceDeclaration, is ModuleDeclaration -> { /* These statements aren't supported in JS (ignore them) */ } else -> raiseConcern("Unexpected top level entity type <${this::class}>") { } } - return returnTypeConstraints + return null } fun List.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { @@ -199,10 +201,15 @@ fun List.calculateConstraints(owner: PropertyOwner, path: P fun ModuleDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) = declarations.calculateConstraints(owner, path) fun ModuleDeclaration.introduceTypes(exportResolver: ExportResolver) : ModuleDeclaration { - val scope = Scope() + val scope = Scope(null) val pathWalker = PathWalker() calculateConstraints(scope, pathWalker) - //TODO check other paths + + if (pathWalker.startNextPath()) { + //TODO check other paths + raiseConcern("Conditional at top level not allowed!") { } + } + val declarations = exportResolver.resolve(scope) return copy(declarations = declarations) } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt index 29b3b7d22..a676ea724 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt @@ -1,7 +1,5 @@ package org.jetbrains.dukat.js.type.constraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner - interface Constraint { operator fun plusAssign(other: Constraint) @@ -11,5 +9,5 @@ interface Constraint { } } - fun resolve(owner: PropertyOwner) : Constraint + fun resolve() : Constraint } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt index 1f4b8b37c..60ee30b6d 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt @@ -7,8 +7,6 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstrain import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -import javax.lang.model.type.NoType class CompositeConstraint(private val constraints: MutableSet) : Constraint { constructor(vararg constraints: Constraint) : this(mutableSetOf(*constraints)) @@ -32,8 +30,8 @@ class CompositeConstraint(private val constraints: MutableSet) : Con } } - override fun resolve(owner: PropertyOwner): Constraint { - val resolvedConstraints = getFlatConstraints().map { it.resolve(owner) } + override fun resolve(): Constraint { + val resolvedConstraints = getFlatConstraints().map { it.resolve() } return when { resolvedConstraints.contains(NumberTypeConstraint) -> NumberTypeConstraint diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt index 07f0d7bc6..14d7092b1 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt @@ -9,8 +9,8 @@ import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class UnionTypeConstraint( val types: List ) : ImmutableConstraint { - override fun resolve(owner: PropertyOwner): Constraint { - val resolvedTypes = types.map { it.resolve(owner) }.filter { it != RecursiveConstraint } + override fun resolve(): Constraint { + val resolvedTypes = types.map { it.resolve() }.filter { it != RecursiveConstraint } return when (resolvedTypes.size) { 0 -> NoTypeConstraint diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ResolvedConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ResolvedConstraint.kt index feaf34241..dbcb559f6 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ResolvedConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ResolvedConstraint.kt @@ -1,8 +1,7 @@ package org.jetbrains.dukat.js.type.constraint.immutable.resolved import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner interface ResolvedConstraint : ImmutableConstraint { - override fun resolve(owner: PropertyOwner) = this + override fun resolve() = this } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt index c0851c369..e46ec173c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt @@ -3,7 +3,7 @@ package org.jetbrains.dukat.js.type.constraint.properties import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -class ClassConstraint(prototype: ObjectConstraint = ObjectConstraint()) : PropertyOwnerConstraint { +class ClassConstraint(parent: PropertyOwner, prototype: ObjectConstraint = ObjectConstraint(parent)) : PropertyOwnerConstraint(parent) { val propertyNames: Set get() = staticMembers.keys @@ -21,11 +21,11 @@ class ClassConstraint(prototype: ObjectConstraint = ObjectConstraint()) : Proper return staticMembers[name] } - override fun resolve(owner: PropertyOwner): ClassConstraint { - val resolvedConstraint = ClassConstraint() + override fun resolve(): ClassConstraint { + val resolvedConstraint = ClassConstraint(owner) propertyNames.forEach { - resolvedConstraint[it] = this[it]!!.resolve(owner) + resolvedConstraint[it] = this[it]!!.resolve() } return resolvedConstraint diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt index 1464bc617..72091a41a 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt @@ -12,17 +12,17 @@ class FunctionConstraint( ) : ImmutableConstraint { //TODO make property owner (since functions technically are, in javascript) private var isResolving = false - override fun resolve(owner: PropertyOwner): FunctionConstraint { - if (!isResolving) { + override fun resolve(): FunctionConstraint { + return if (!isResolving) { isResolving = true val resolvedConstraint = FunctionConstraint( - returnConstraints.resolve(owner), - parameterConstraints.map { (name, constraint) -> name to constraint.resolve(owner) } + returnConstraints.resolve(), + parameterConstraints.map { (name, constraint) -> name to constraint.resolve() } ) isResolving = false - return resolvedConstraint + resolvedConstraint } else { - return FunctionConstraint( + FunctionConstraint( RecursiveConstraint, parameterConstraints.map { (name, _) -> name to NoTypeConstraint } ) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt index 83d352705..7fb83c15c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt @@ -5,8 +5,9 @@ import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.panic.raiseConcern class ObjectConstraint( + owner: PropertyOwner, val instantiatedClass: PropertyOwnerConstraint? = null -) : PropertyOwnerConstraint { +) : PropertyOwnerConstraint(owner) { val propertyNames: Set get() = properties.keys @@ -35,21 +36,21 @@ class ObjectConstraint( } } - override fun resolve(owner: PropertyOwner): ObjectConstraint { + override fun resolve(): ObjectConstraint { val resolvedConstraint = if (instantiatedClass == null) { - ObjectConstraint() + ObjectConstraint(owner) } else { - val resolvedClass = instantiatedClass.resolve(owner) + val resolvedClass = instantiatedClass.resolve() if (resolvedClass is PropertyOwnerConstraint) { - ObjectConstraint(resolvedClass) + ObjectConstraint(owner, resolvedClass) } else { - raiseConcern("Instantiating constraint which cannot be instantiated!") { ObjectConstraint() } + raiseConcern("Instantiating constraint which cannot be instantiated!") { ObjectConstraint(owner) } } } propertyNames.forEach { - resolvedConstraint[it] = this[it]!!.resolve(owner) + resolvedConstraint[it] = this[it]!!.resolve() } return resolvedConstraint diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt index 1f26b5c86..4ab9c62fa 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt @@ -3,4 +3,4 @@ package org.jetbrains.dukat.js.type.constraint.properties import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -interface PropertyOwnerConstraint : PropertyOwner, ImmutableConstraint \ No newline at end of file +abstract class PropertyOwnerConstraint(override val owner: PropertyOwner) : PropertyOwner, ImmutableConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt index d6da0e118..6b8a1606c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt @@ -6,7 +6,7 @@ import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.panic.raiseConcern -abstract class PropertyOwnerReferenceConstraint : PropertyOwnerConstraint { +abstract class PropertyOwnerReferenceConstraint(parent: PropertyOwner) : PropertyOwnerConstraint(parent) { private val modifiedProperties = LinkedHashMap() override fun set(name: String, data: Constraint) { @@ -21,7 +21,7 @@ abstract class PropertyOwnerReferenceConstraint : PropertyOwnerConstraint { * Called at resolving stage, * to apply properties to the resolved reference. */ - protected fun Constraint.resolveWithProperties(owner: PropertyOwner) : Constraint { + protected fun Constraint.resolveWithProperties() : Constraint { if(this is PropertyOwner) { modifiedProperties.forEach { (name, constraint) -> //TODO take composite constraints into account here @@ -29,6 +29,6 @@ abstract class PropertyOwnerReferenceConstraint : PropertyOwnerConstraint { } } - return this.resolve(owner) + return this.resolve() } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt index 6860b1e2f..0e281d0c4 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt @@ -3,34 +3,44 @@ package org.jetbrains.dukat.js.type.constraint.reference import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint -import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.panic.raiseConcern open class ReferenceConstraint( private val identifier: IdentifierEntity, - private val parent: PropertyOwnerConstraint? = null -) : PropertyOwnerReferenceConstraint() { - override fun resolve(owner: PropertyOwner): Constraint { - val referenceOwner = if (parent != null) { - val resolvedParent = parent.resolve(owner) + owner: PropertyOwner +) : PropertyOwnerReferenceConstraint(owner) { + private tailrec fun resolveInOwner(owner: PropertyOwner): Constraint? { + val resolvedOwner = if(owner is Constraint) { + val resolvedConstraint = owner.resolve() - if(resolvedParent is PropertyOwner) { - resolvedParent + if (resolvedConstraint is PropertyOwner) { + resolvedConstraint } else { - raiseConcern("Accessing property of non-property-owner") { } - return CompositeConstraint() + raiseConcern("Accessing property of non-property-owner") { null } } } else { owner } - val dereferencedConstraint = referenceOwner[identifier] + return if(resolvedOwner != null) { + val dereferencedConstraint = resolvedOwner[identifier] - return if (dereferencedConstraint != null && dereferencedConstraint !is ReferenceConstraint) { - dereferencedConstraint.resolveWithProperties(referenceOwner) + if (dereferencedConstraint != null && dereferencedConstraint !is ReferenceConstraint) { + dereferencedConstraint.resolveWithProperties() + } else { + if (resolvedOwner.owner != null) { + resolveInOwner(resolvedOwner.owner!!) + } else { + null + } + } } else { - this + null } } + + override fun resolve(): Constraint { + return resolveInOwner(owner) ?: CompositeConstraint() + } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt index ddc1f5d33..55dd328ac 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt @@ -4,14 +4,13 @@ import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class CallArgumentConstraint( private val callTarget: Constraint, private val argumentNum: Int ) : ImmutableConstraint { - override fun resolve(owner: PropertyOwner): Constraint { - val functionConstraint = callTarget.resolve(owner) + override fun resolve(): Constraint { + val functionConstraint = callTarget.resolve() return if (functionConstraint is FunctionConstraint) { if (functionConstraint.parameterConstraints.size >= argumentNum) { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt index 60e1f0bc5..f767a8665 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt @@ -6,15 +6,16 @@ import org.jetbrains.dukat.js.type.constraint.reference.PropertyOwnerReferenceCo import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class CallResultConstraint( + owner: PropertyOwner, private val callTarget: Constraint -) : PropertyOwnerReferenceConstraint() { - override fun resolve(owner: PropertyOwner): Constraint { - val functionConstraint = callTarget.resolve(owner) +) : PropertyOwnerReferenceConstraint(owner) { + override fun resolve(): Constraint { + val functionConstraint = callTarget.resolve() return if (functionConstraint is FunctionConstraint) { - functionConstraint.returnConstraints.resolveWithProperties(owner) + functionConstraint.returnConstraints.resolveWithProperties() } else { - CallResultConstraint(functionConstraint) + CallResultConstraint(owner, functionConstraint) } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt index 7a26369fa..82242b9d4 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt @@ -7,7 +7,7 @@ import org.jetbrains.dukat.tsmodel.TopLevelDeclaration class GeneralExportResolver : ExportResolver { override fun resolve(scope: Scope) : List { return scope.propertyNames.mapNotNull { propertyName -> - val resolvedConstraint = scope[propertyName].resolve(scope) + val resolvedConstraint = scope[propertyName].resolve() resolvedConstraint.toDeclaration(propertyName) } } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt index 500fccfdc..1602bab10 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt @@ -10,6 +10,8 @@ import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaratio import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration interface PropertyOwner { + val owner: PropertyOwner? + operator fun set(name: String, data: Constraint) operator fun set(identifier: IdentifierEntity, data: Constraint) { @@ -36,27 +38,6 @@ interface PropertyOwner { } } - /* - fun has(name: String) : Boolean - - fun has(identifier: IdentifierEntity) : Boolean { - return has(identifier.value) - } - - fun has(identifierExpression: IdentifierExpressionDeclaration) : Boolean { - return has(identifierExpression.identifier) - } - - fun has(propertyAccessExpression: PropertyAccessExpressionDeclaration) : Boolean - - fun has(expression: ExpressionDeclaration) : Boolean { - return when (expression) { - is IdentifierExpressionDeclaration -> has(expression) - is PropertyAccessExpressionDeclaration -> has(expression) - else -> raiseConcern("Cannot get variable described by expression of type <${expression::class}>") { false } - } - } - */ operator fun get(name: String) : Constraint? diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt index 84ade79ba..7c34061b2 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt @@ -4,7 +4,7 @@ import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.reference.ReferenceConstraint -class Scope : PropertyOwner { +class Scope(override val owner: PropertyOwner?) : PropertyOwner { val propertyNames: Set get() = properties.keys @@ -15,6 +15,6 @@ class Scope : PropertyOwner { } override fun get(name: String): Constraint { - return properties[name] ?: ReferenceConstraint(IdentifierEntity(name)) + return properties[name] ?: ReferenceConstraint(IdentifierEntity(name), this) } } \ No newline at end of file From 098eb07ec7b96eb5effff16e452d81c7896fdf3d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Nov 2019 13:47:55 +0100 Subject: [PATCH 086/172] Move 'calculateConstraint' and 'addTo' to a seperate file --- .../js/type/analysis/calculateConstraints.kt | 196 ++++++++++++++++++ .../dukat/js/type/analysis/introduceTypes.kt | 192 ----------------- 2 files changed, 196 insertions(+), 192 deletions(-) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt new file mode 100644 index 000000000..a2a027cde --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt @@ -0,0 +1,196 @@ +package org.jetbrains.dukat.js.type.analysis + +import org.jetbrains.dukat.astCommon.IdentifierEntity +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint +import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint +import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.property_owner.Scope +import org.jetbrains.dukat.panic.raiseConcern +import org.jetbrains.dukat.tsmodel.BlockDeclaration +import org.jetbrains.dukat.tsmodel.ClassDeclaration +import org.jetbrains.dukat.tsmodel.ConstructorDeclaration +import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration +import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.IfStatementDeclaration +import org.jetbrains.dukat.tsmodel.InterfaceDeclaration +import org.jetbrains.dukat.tsmodel.MemberDeclaration +import org.jetbrains.dukat.tsmodel.ModifierDeclaration +import org.jetbrains.dukat.tsmodel.ModuleDeclaration +import org.jetbrains.dukat.tsmodel.PropertyDeclaration +import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration +import org.jetbrains.dukat.tsmodel.TopLevelDeclaration +import org.jetbrains.dukat.tsmodel.VariableDeclaration +import org.jetbrains.dukat.tsmodel.WhileStatementDeclaration + +fun List.pack() : FunctionConstraint { + return if (size == 1) { + this[0] + } else { + val parameters = mutableListOf>>() + + forEach { + it.parameterConstraints.forEachIndexed { index, (name, constraint) -> + if (parameters.size <= index) { + parameters.add(index, name to mutableListOf()) + } + + parameters[index].second.add(constraint) + } + } + + FunctionConstraint( + returnConstraints = UnionTypeConstraint(map { it.returnConstraints }), + parameterConstraints = parameters.map { (name, constraints) -> name to UnionTypeConstraint(constraints) } + ) + } +} + +fun FunctionDeclaration.addTo(owner: PropertyOwner) { + if (this.body != null) { + val pathWalker = PathWalker() + + val versions = mutableListOf() + + do { + val functionScope = Scope(owner) + + val parameterConstraints = MutableList(parameters.size) { i -> + // Store constraints of parameters in scope, + // and in parameter list (in case the variable is replaced) + val parameterConstraint = CompositeConstraint() + functionScope[parameters[i].name] = parameterConstraint + parameters[i].name to parameterConstraint + } + + val returnTypeConstraints = body!!.calculateConstraints(functionScope, pathWalker) ?: VoidTypeConstraint + + versions.add(FunctionConstraint( + returnConstraints = returnTypeConstraints, + parameterConstraints = parameterConstraints + )) + } while (pathWalker.startNextPath()) + + owner[name] = versions.pack() + } +} + +@Suppress("UNUSED") +fun ConstructorDeclaration.addTo(@Suppress("UNUSED_PARAMETER") owner: PropertyOwner) { + raiseConcern("Cannot create header for constructor.") { } //TODO add constructor body to AST +} + +fun PropertyDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { + owner[name] = initializer?.calculateConstraints(owner, path) ?: NoTypeConstraint +} + +fun MemberDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { + when (this) { + is FunctionDeclaration -> this.addTo(owner) + is PropertyDeclaration -> this.addTo(owner, path) + else -> raiseConcern("Unexpected member entity type <${this::class}> in object.") { this } + } +} + +fun MemberDeclaration.addToClass(owner: ClassConstraint, path: PathWalker) { + when (this) { + is ConstructorDeclaration -> this.addTo(owner) + is FunctionDeclaration -> if (this.modifiers.contains(ModifierDeclaration.STATIC_KEYWORD)) { + this.addTo(owner) + } else { + val ownerPrototype = owner["prototype"] + + if (ownerPrototype is PropertyOwner) { + this.addTo(ownerPrototype) + } else { + raiseConcern("Class prototype corrupt! Cannot add members.") { } + } + } + is PropertyDeclaration -> this.addTo(owner, path) + else -> raiseConcern("Unexpected member entity type <${this::class}> in class.") { this } + } +} + +fun ClassDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { + val className = name // Needed for smart cast + if(className is IdentifierEntity) { + val classConstraint = ClassConstraint(owner) + + members.forEach { it.addToClass(classConstraint, path) } + + owner[className.value] = classConstraint + } else { + raiseConcern("Cannot convert class with name of type <${className::class}>.") { } + } +} + +fun BlockDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { + return statements.calculateConstraints(owner, path) +} + +fun VariableDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { + owner[name] = initializer?.calculateConstraints(owner, path) ?: NoTypeConstraint +} + +fun IfStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { + condition.calculateConstraints(owner, path) += BooleanTypeConstraint + + return when (path.getNextDirection()) { + PathWalker.Direction.First -> thenStatement.calculateConstraints(owner, path) + PathWalker.Direction.Second -> elseStatement?.calculateConstraints(owner, path) + } +} + +fun WhileStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { + condition.calculateConstraints(owner, path) += BooleanTypeConstraint + + return when (path.getNextDirection()) { + PathWalker.Direction.First -> statement.calculateConstraints(owner, path) + PathWalker.Direction.Second -> null + } +} + +fun ExpressionStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) { + expression.calculateConstraints(owner, path) +} + +fun ReturnStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { + return expression?.calculateConstraints(owner, path) ?: VoidTypeConstraint +} + +fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { + when (this) { + is FunctionDeclaration -> this.addTo(owner) + is ClassDeclaration -> this.addTo(owner, path) + is VariableDeclaration -> this.addTo(owner, path) + is IfStatementDeclaration -> return this.calculateConstraints(owner, path) + is WhileStatementDeclaration -> return this.calculateConstraints(owner, path) + is ExpressionStatementDeclaration -> this.calculateConstraints(owner, path) + is BlockDeclaration -> return this.calculateConstraints(owner, path) + is ReturnStatementDeclaration -> return this.calculateConstraints(owner, path) + is InterfaceDeclaration, + is ModuleDeclaration -> { /* These statements aren't supported in JS (ignore them) */ } + else -> raiseConcern("Unexpected top level entity type <${this::class}>") { } + } + + return null +} + +fun List.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { + this.forEach { statement -> + val statementReturnTypeConstraints = statement.calculateConstraints(owner, path) + + if(statementReturnTypeConstraints != null) { + return statementReturnTypeConstraints + } + } + + return null +} + +fun ModuleDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) = declarations.calculateConstraints(owner, path) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index 4c1560740..b49e4b114 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -1,204 +1,12 @@ package org.jetbrains.dukat.js.type.analysis -import org.jetbrains.dukat.astCommon.IdentifierEntity -import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint -import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint -import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint -import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint -import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint -import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint -import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.js.type.property_owner.Scope import org.jetbrains.dukat.js.type.export_resolution.GeneralExportResolver import org.jetbrains.dukat.js.type.export_resolution.ExportResolver import org.jetbrains.dukat.panic.raiseConcern -import org.jetbrains.dukat.tsmodel.BlockDeclaration -import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.ModuleDeclaration import org.jetbrains.dukat.tsmodel.SourceFileDeclaration import org.jetbrains.dukat.tsmodel.SourceSetDeclaration -import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration -import org.jetbrains.dukat.tsmodel.FunctionDeclaration -import org.jetbrains.dukat.tsmodel.IfStatementDeclaration -import org.jetbrains.dukat.tsmodel.InterfaceDeclaration -import org.jetbrains.dukat.tsmodel.MemberDeclaration -import org.jetbrains.dukat.tsmodel.ModifierDeclaration -import org.jetbrains.dukat.tsmodel.PropertyDeclaration -import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration -import org.jetbrains.dukat.tsmodel.TopLevelDeclaration -import org.jetbrains.dukat.tsmodel.VariableDeclaration -import org.jetbrains.dukat.tsmodel.WhileStatementDeclaration - -fun List.pack() : FunctionConstraint { - return if (size == 1) { - this[0] - } else { - val parameters = mutableListOf>>() - - forEach { - it.parameterConstraints.forEachIndexed { index, (name, constraint) -> - if (parameters.size <= index) { - parameters.add(index, name to mutableListOf()) - } - - parameters[index].second.add(constraint) - } - } - - FunctionConstraint( - returnConstraints = UnionTypeConstraint(map { it.returnConstraints }), - parameterConstraints = parameters.map { (name, constraints) -> name to UnionTypeConstraint(constraints) } - ) - } -} - -fun FunctionDeclaration.addTo(owner: PropertyOwner) { - if (this.body != null) { - val pathWalker = PathWalker() - - val versions = mutableListOf() - - do { - val functionScope = Scope(owner) - - val parameterConstraints = MutableList(parameters.size) { i -> - // Store constraints of parameters in scope, - // and in parameter list (in case the variable is replaced) - val parameterConstraint = CompositeConstraint() - functionScope[parameters[i].name] = parameterConstraint - parameters[i].name to parameterConstraint - } - - val returnTypeConstraints = body!!.calculateConstraints(functionScope, pathWalker) ?: VoidTypeConstraint - - versions.add(FunctionConstraint( - returnConstraints = returnTypeConstraints, - parameterConstraints = parameterConstraints - )) - } while (pathWalker.startNextPath()) - - owner[name] = versions.pack() - } -} - -/* -fun ConstructorDeclaration.addTo(owner: PropertyOwner) { - // TODO add body to constructor in AST and process it like a function -} - -fun InterfaceDeclaration.addTo(owner: PropertyOwner) -*/ - -fun PropertyDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { - owner[name] = initializer?.calculateConstraints(owner, path) ?: NoTypeConstraint -} - -fun MemberDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { - when (this) { - is FunctionDeclaration -> this.addTo(owner) - is PropertyDeclaration -> this.addTo(owner, path) - else -> raiseConcern("Unexpected member entity type <${this::class}>") { this } - } -} - -fun MemberDeclaration.addToClass(owner: ClassConstraint, path: PathWalker) { - when (this) { - is FunctionDeclaration -> if (this.modifiers.contains(ModifierDeclaration.STATIC_KEYWORD)) { - this.addTo(owner) - } else { - val ownerPrototype = owner["prototype"] - - if (ownerPrototype is PropertyOwner) { - this.addTo(ownerPrototype) - } else { - raiseConcern("Class prototype corrupt! Cannot add members.") { } - } - } - is PropertyDeclaration -> this.addTo(owner, path) - else -> raiseConcern("Unexpected member entity type <${this::class}>") { this } - } -} - -fun ClassDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { - val className = name // Needed for smart cast - if(className is IdentifierEntity) { - val classConstraint = ClassConstraint(owner) - - members.forEach { it.addToClass(classConstraint, path) } - - owner[className.value] = classConstraint - } else { - raiseConcern("Cannot convert class with name of type <${className::class}>.") { } - } -} - -fun BlockDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { - return statements.calculateConstraints(owner, path) -} - -fun VariableDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { - owner[name] = initializer?.calculateConstraints(owner, path) ?: NoTypeConstraint -} - -fun IfStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { - condition.calculateConstraints(owner, path) += BooleanTypeConstraint - - return when (path.getNextDirection()) { - PathWalker.Direction.First -> thenStatement.calculateConstraints(owner, path) - PathWalker.Direction.Second -> elseStatement?.calculateConstraints(owner, path) - } -} - -fun WhileStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { - condition.calculateConstraints(owner, path) += BooleanTypeConstraint - - return when (path.getNextDirection()) { - PathWalker.Direction.First -> statement.calculateConstraints(owner, path) - PathWalker.Direction.Second -> null - } -} - -fun ExpressionStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) { - expression.calculateConstraints(owner, path) -} - -fun ReturnStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { - return expression?.calculateConstraints(owner, path) ?: VoidTypeConstraint -} - -fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { - when (this) { - is FunctionDeclaration -> this.addTo(owner) - is ClassDeclaration -> this.addTo(owner, path) - is VariableDeclaration -> this.addTo(owner, path) - is IfStatementDeclaration -> return this.calculateConstraints(owner, path) - is WhileStatementDeclaration -> return this.calculateConstraints(owner, path) - is ExpressionStatementDeclaration -> this.calculateConstraints(owner, path) - is BlockDeclaration -> return this.calculateConstraints(owner, path) - is ReturnStatementDeclaration -> return this.calculateConstraints(owner, path) - is InterfaceDeclaration, - is ModuleDeclaration -> { /* These statements aren't supported in JS (ignore them) */ } - else -> raiseConcern("Unexpected top level entity type <${this::class}>") { } - } - - return null -} - -fun List.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { - this.forEach { statement -> - val statementReturnTypeConstraints = statement.calculateConstraints(owner, path) - - if(statementReturnTypeConstraints != null) { - return statementReturnTypeConstraints - } - } - - return null -} - -fun ModuleDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) = declarations.calculateConstraints(owner, path) fun ModuleDeclaration.introduceTypes(exportResolver: ExportResolver) : ModuleDeclaration { val scope = Scope(null) From 02a524712b4c711d0a01aab8126bcb158ff4593c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Nov 2019 15:11:42 +0100 Subject: [PATCH 087/172] Restrict exports to CommonJS compatible exports --- .../data/javascript/class/memberAccess.d.kt | 8 ---- .../data/javascript/class/memberAccess.d.ts | 6 ++- .../javascript/class/memberModification.d.ts | 8 ++-- .../test/data/javascript/class/methods.d.ts | 2 + .../test/data/javascript/class/static.d.ts | 2 + .../test/data/javascript/conditional/if.d.ts | 26 ++++++++----- .../data/javascript/conditional/while.d.ts | 20 +++++----- .../test/data/javascript/function/asType.d.ts | 3 ++ .../data/javascript/function/function.d.ts | 37 ++++++++++--------- .../test/data/javascript/function/nested.d.kt | 4 -- .../test/data/javascript/function/nested.d.ts | 5 ++- .../test/data/javascript/function/unit.d.ts | 15 +++++--- .../data/javascript/instance/instance.d.ts | 6 ++- .../data/javascript/literal/literals.d.ts | 10 ++--- .../test/data/javascript/misc/operators.d.ts | 20 +++++----- .../test/data/javascript/misc/random.d.kt | 14 ------- .../test/data/javascript/misc/random.d.ts | 8 +++- .../data/javascript/object/construct.d.kt | 4 +- .../data/javascript/object/construct.d.ts | 5 ++- .../test/data/javascript/object/modified.d.ts | 8 +++- .../test/data/javascript/object/object.d.ts | 2 +- .../data/javascript/reference/function.d.ts | 3 ++ .../data/javascript/reference/property.d.ts | 5 ++- .../data/javascript/reference/recursive.d.ts | 4 +- .../data/javascript/reference/undefined.d.ts | 4 +- .../data/javascript/reference/variable.d.kt | 6 --- .../data/javascript/reference/variable.d.ts | 6 ++- .../dukat/js/type/analysis/introduceTypes.kt | 22 +++++++---- .../CommonJSEnvironmentProvider.kt | 19 ++++++++++ .../CommonJSExportResolver.kt | 35 ++++++++++++++++++ .../EmptyEnvironmentProvider.kt | 9 +++++ .../export_resolution/EnvironmentProvider.kt | 7 ++++ 32 files changed, 220 insertions(+), 113 deletions(-) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSEnvironmentProvider.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSExportResolver.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EmptyEnvironmentProvider.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EnvironmentProvider.kt diff --git a/compiler/test/data/javascript/class/memberAccess.d.kt b/compiler/test/data/javascript/class/memberAccess.d.kt index 0a49ef527..5b4d8b781 100644 --- a/compiler/test/data/javascript/class/memberAccess.d.kt +++ b/compiler/test/data/javascript/class/memberAccess.d.kt @@ -15,14 +15,6 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external open class Literals { - companion object { - fun getStringLiteral(): String - fun getNumberLiteral(): Number - fun getBooleanLiteral(): Boolean - } -} - external var str: String external var num: Number diff --git a/compiler/test/data/javascript/class/memberAccess.d.ts b/compiler/test/data/javascript/class/memberAccess.d.ts index 3032fd088..1c396e6fb 100644 --- a/compiler/test/data/javascript/class/memberAccess.d.ts +++ b/compiler/test/data/javascript/class/memberAccess.d.ts @@ -15,4 +15,8 @@ class Literals { var str = Literals.getStringLiteral() var num = Literals.getNumberLiteral() -var bool = Literals.getBooleanLiteral() \ No newline at end of file +var bool = Literals.getBooleanLiteral() + +module.exports.str = str +module.exports.num = num +module.exports.bool = bool \ No newline at end of file diff --git a/compiler/test/data/javascript/class/memberModification.d.ts b/compiler/test/data/javascript/class/memberModification.d.ts index 6396effdf..8610e7897 100644 --- a/compiler/test/data/javascript/class/memberModification.d.ts +++ b/compiler/test/data/javascript/class/memberModification.d.ts @@ -16,6 +16,8 @@ class ModifiedLiterals { ModifiedLiterals.getStringLiteral = ModifiedLiterals.getNumberLiteral ModifiedLiterals.getBooleanLiteral = ModifiedLiterals.getNumberLiteral -var falseStr = ModifiedLiterals.getStringLiteral() -var trueNum = ModifiedLiterals.getNumberLiteral() -var falseBool = ModifiedLiterals.getBooleanLiteral() \ No newline at end of file + +module.exports.ModifiedLiterals = ModifiedLiterals +module.exports.falseStr = ModifiedLiterals.getStringLiteral() +module.exports.trueNum = ModifiedLiterals.getNumberLiteral() +module.exports.falseBool = ModifiedLiterals.getBooleanLiteral() \ No newline at end of file diff --git a/compiler/test/data/javascript/class/methods.d.ts b/compiler/test/data/javascript/class/methods.d.ts index a5ba57b8d..0248612f3 100644 --- a/compiler/test/data/javascript/class/methods.d.ts +++ b/compiler/test/data/javascript/class/methods.d.ts @@ -12,3 +12,5 @@ class Literals { return false } } + +module.exports.Literals = Literals \ No newline at end of file diff --git a/compiler/test/data/javascript/class/static.d.ts b/compiler/test/data/javascript/class/static.d.ts index 7d4499769..4983cff2e 100644 --- a/compiler/test/data/javascript/class/static.d.ts +++ b/compiler/test/data/javascript/class/static.d.ts @@ -12,3 +12,5 @@ class Literals { return false } } + +module.exports.Literals = Literals diff --git a/compiler/test/data/javascript/conditional/if.d.ts b/compiler/test/data/javascript/conditional/if.d.ts index e410eb446..465e9d3fb 100644 --- a/compiler/test/data/javascript/conditional/if.d.ts +++ b/compiler/test/data/javascript/conditional/if.d.ts @@ -1,15 +1,21 @@ -function max(a, b) { - if (a > b) - return a - - return b +function isNum(x) { + return typeof x == "number" } -function negate(a) { - if(isNum(a)) { - return -a - } else { - return !a +module.exports = { + max(a, b) { + if (a > b) + return a + + return b + }, + + negate(a) { + if(isNum(a)) { + return -a + } else { + return !a + } } } diff --git a/compiler/test/data/javascript/conditional/while.d.ts b/compiler/test/data/javascript/conditional/while.d.ts index b4b4304c0..a84a4f52e 100644 --- a/compiler/test/data/javascript/conditional/while.d.ts +++ b/compiler/test/data/javascript/conditional/while.d.ts @@ -1,15 +1,17 @@ -function product(arr) { - let product +module.exports = { + product(arr) { + let product - let i = 0 - while (typeof arr[i++] == "number") { - if (product == undefined) { - product = 1 + let i = 0 + while (typeof arr[i++] == "number") { + if (product == undefined) { + product = 1 + } + + product *= arr[i - 1] } - product *= arr[i - 1] + return product } - - return product } \ No newline at end of file diff --git a/compiler/test/data/javascript/function/asType.d.ts b/compiler/test/data/javascript/function/asType.d.ts index f09e9534f..f622f7e30 100644 --- a/compiler/test/data/javascript/function/asType.d.ts +++ b/compiler/test/data/javascript/function/asType.d.ts @@ -6,3 +6,6 @@ function minus(a, b) { function getMinus() { return minus } + +exports.minus = minus +exports.getMinus = getMinus \ No newline at end of file diff --git a/compiler/test/data/javascript/function/function.d.ts b/compiler/test/data/javascript/function/function.d.ts index 2e8f90fdb..93558bc58 100644 --- a/compiler/test/data/javascript/function/function.d.ts +++ b/compiler/test/data/javascript/function/function.d.ts @@ -1,21 +1,24 @@ -function numBinaryFun(a, b) { - return a - b -} -function numUnaryFun(a) { - var b = a - a = "text" - return b++ -} +module.exports = { + numBinaryFun(a, b) { + return a - b + }, -function boolBinaryFun(a, b) { - return a == b -} + numUnaryFun(a) { + var b = a + a = "text" + return b++ + }, -function boolUnaryFun(a) { - return !a -} + boolBinaryFun(a, b) { + return a == b + }, + + boolUnaryFun(a) { + return !a + }, -function anyFun(a, b) { - return a + b -} \ No newline at end of file + anyFun(a, b) { + return a + b + } +} diff --git a/compiler/test/data/javascript/function/nested.d.kt b/compiler/test/data/javascript/function/nested.d.kt index 73c84bd0c..c2084ccbd 100644 --- a/compiler/test/data/javascript/function/nested.d.kt +++ b/compiler/test/data/javascript/function/nested.d.kt @@ -17,8 +17,4 @@ import org.w3c.xhr.* external fun numFun(): Number -external var value: String - -external fun bar(): String - external fun strFun(): String \ No newline at end of file diff --git a/compiler/test/data/javascript/function/nested.d.ts b/compiler/test/data/javascript/function/nested.d.ts index 4c4f96f5b..b774c49e0 100644 --- a/compiler/test/data/javascript/function/nested.d.ts +++ b/compiler/test/data/javascript/function/nested.d.ts @@ -20,4 +20,7 @@ function strFun() { var value = 3 return bar() -} \ No newline at end of file +} + +exports.numFun = numFun +exports.strFun = strFun \ No newline at end of file diff --git a/compiler/test/data/javascript/function/unit.d.ts b/compiler/test/data/javascript/function/unit.d.ts index 769af0093..4d0aeebfc 100644 --- a/compiler/test/data/javascript/function/unit.d.ts +++ b/compiler/test/data/javascript/function/unit.d.ts @@ -1,8 +1,11 @@ -function emptyReturnFunction() { - console.log("Nothing is happening!") - return; -} -function unitFunction() { - console.log("Nothing is happening!") +module.exports = { + emptyReturnFunction() { + console.log("Nothing is happening!") + return; + }, + + unitFunction() { + console.log("Nothing is happening!") + } } \ No newline at end of file diff --git a/compiler/test/data/javascript/instance/instance.d.ts b/compiler/test/data/javascript/instance/instance.d.ts index 826a0ab90..6475e1da4 100644 --- a/compiler/test/data/javascript/instance/instance.d.ts +++ b/compiler/test/data/javascript/instance/instance.d.ts @@ -7,4 +7,8 @@ class C { var o = new C() -var str = o.foo() \ No newline at end of file +var str = o.foo() + +module.exports.C = C +module.exports.o = o +module.exports.str = str \ No newline at end of file diff --git a/compiler/test/data/javascript/literal/literals.d.ts b/compiler/test/data/javascript/literal/literals.d.ts index 577116159..8b36c6760 100644 --- a/compiler/test/data/javascript/literal/literals.d.ts +++ b/compiler/test/data/javascript/literal/literals.d.ts @@ -1,5 +1,5 @@ -var num, bool, str; - -num = 3; -bool = true; -str = "text"; \ No newline at end of file +module.exports = { + num: 3, + bool: true, + str: "text" +} \ No newline at end of file diff --git a/compiler/test/data/javascript/misc/operators.d.ts b/compiler/test/data/javascript/misc/operators.d.ts index b10dd292b..df4dc0e86 100644 --- a/compiler/test/data/javascript/misc/operators.d.ts +++ b/compiler/test/data/javascript/misc/operators.d.ts @@ -1,12 +1,14 @@ -function typeOf(o) { - return typeof o -} +module.exports = { + typeOf(o) { + return typeof o + }, -function instanceOfObject(o) { - return o instanceof Object -} + instanceOfObject(o) { + return o instanceof Object + }, -function keyInObj(key, obj) { - return key in obj; -} + keyInObj(key, obj) { + return key in obj; + } +} \ No newline at end of file diff --git a/compiler/test/data/javascript/misc/random.d.kt b/compiler/test/data/javascript/misc/random.d.kt index 204c9bb5f..b1eee3c21 100644 --- a/compiler/test/data/javascript/misc/random.d.kt +++ b/compiler/test/data/javascript/misc/random.d.kt @@ -25,20 +25,6 @@ external object _ { fun isEmpty(obj: Any?): Boolean } -external fun values(obj: Any?): Any? - -external fun keys(obj: Any?): Any? - -external fun negate(predicate: Any?): Boolean - -external fun isArray(obj: Any?): Boolean - -external fun isObject(obj: Any?): Boolean - -external fun isElement(obj: Any?): Boolean - -external fun isEmpty(obj: Any?): Boolean - external fun keyInObj(value: Any?, key: Any?, obj: Any?): Boolean external fun createPredicateIndexFinder(array: Any?, predicate: Any?, context: Any?, dir: Any?): Number diff --git a/compiler/test/data/javascript/misc/random.d.ts b/compiler/test/data/javascript/misc/random.d.ts index 7bd666c5e..31fa60fba 100644 --- a/compiler/test/data/javascript/misc/random.d.ts +++ b/compiler/test/data/javascript/misc/random.d.ts @@ -80,4 +80,10 @@ function createPredicateIndexFinder(array, predicate, context, dir) { function isArrayLike(collection) { var length = getLength(collection); return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; -} \ No newline at end of file +} + + +module.exports._ = _ +module.exports.keyInObj = keyInObj +module.exports.createPredicateIndexFinder = createPredicateIndexFinder +module.exports.isArrayLike = isArrayLike diff --git a/compiler/test/data/javascript/object/construct.d.kt b/compiler/test/data/javascript/object/construct.d.kt index c9401796f..fd414b5a6 100644 --- a/compiler/test/data/javascript/object/construct.d.kt +++ b/compiler/test/data/javascript/object/construct.d.kt @@ -30,6 +30,4 @@ external object v { var z: Number fun negate(x: Any?, y: Any?, z: Any?): `T$0` var double: `T$0` -} - -external fun negate(x: Any?, y: Any?, z: Any?): `T$0` \ No newline at end of file +} \ No newline at end of file diff --git a/compiler/test/data/javascript/object/construct.d.ts b/compiler/test/data/javascript/object/construct.d.ts index 8f6b00a43..256d4f385 100644 --- a/compiler/test/data/javascript/object/construct.d.ts +++ b/compiler/test/data/javascript/object/construct.d.ts @@ -1,4 +1,3 @@ - var v = {}; v.x = 5; @@ -21,4 +20,6 @@ v.double = {} v.double.x = 2*v.x; v.double.y = 2*v.y; -v.double.z = 2*v.z; \ No newline at end of file +v.double.z = 2*v.z; + +module.exports.v = v \ No newline at end of file diff --git a/compiler/test/data/javascript/object/modified.d.ts b/compiler/test/data/javascript/object/modified.d.ts index baf0dce13..2163bf7d0 100644 --- a/compiler/test/data/javascript/object/modified.d.ts +++ b/compiler/test/data/javascript/object/modified.d.ts @@ -20,4 +20,10 @@ var obj = { function modObj() { obj.b = "text" -} \ No newline at end of file +} + + +module.exports.get2DVector = get2DVector +module.exports.get3DVector = get3DVector +module.exports.obj = obj +module.exports.modObj = modObj \ No newline at end of file diff --git a/compiler/test/data/javascript/object/object.d.ts b/compiler/test/data/javascript/object/object.d.ts index 8fd5befb4..f3885ec2e 100644 --- a/compiler/test/data/javascript/object/object.d.ts +++ b/compiler/test/data/javascript/object/object.d.ts @@ -1,5 +1,5 @@ -var v = { +module.exports.v = { x: 5, y: 5, z: 5, diff --git a/compiler/test/data/javascript/reference/function.d.ts b/compiler/test/data/javascript/reference/function.d.ts index fd4663c8b..170f01ddc 100644 --- a/compiler/test/data/javascript/reference/function.d.ts +++ b/compiler/test/data/javascript/reference/function.d.ts @@ -6,3 +6,6 @@ function numBinaryFun(a, b) { function numBinaryFunWrapper(a, b) { return numBinaryFun(a, b) } + +module.exports.numBinaryFun = numBinaryFun +module.exports.numBinaryFunWrapper = numBinaryFunWrapper \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/property.d.ts b/compiler/test/data/javascript/reference/property.d.ts index 8380e6221..ebc06a354 100644 --- a/compiler/test/data/javascript/reference/property.d.ts +++ b/compiler/test/data/javascript/reference/property.d.ts @@ -6,4 +6,7 @@ class PropertyOwner { function wrapperFun() { return PropertyOwner.property() -} \ No newline at end of file +} + +module.exports.PropertyOwner = PropertyOwner +module.exports.wrapperFun = wrapperFun \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/recursive.d.ts b/compiler/test/data/javascript/reference/recursive.d.ts index 47321f39a..17a444f6e 100644 --- a/compiler/test/data/javascript/reference/recursive.d.ts +++ b/compiler/test/data/javascript/reference/recursive.d.ts @@ -5,4 +5,6 @@ function fibonacci(num) { //Using double minus here, to show that this is a number (for plus this isn't possible) return fibonacci(num - 1) - -fibonacci(num - 2); -} \ No newline at end of file +} + +module.exports.fibonacci = fibonacci \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/undefined.d.ts b/compiler/test/data/javascript/reference/undefined.d.ts index 5ccef2f12..467c89e6b 100644 --- a/compiler/test/data/javascript/reference/undefined.d.ts +++ b/compiler/test/data/javascript/reference/undefined.d.ts @@ -1,3 +1,5 @@ function undefReferenceFun() { return PropertyOwner.property() -} \ No newline at end of file +} + +module.exports.undefReferenceFun = undefReferenceFun \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/variable.d.kt b/compiler/test/data/javascript/reference/variable.d.kt index 5524bf8e2..d1e0d9255 100644 --- a/compiler/test/data/javascript/reference/variable.d.kt +++ b/compiler/test/data/javascript/reference/variable.d.kt @@ -15,12 +15,6 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external var num: Number - -external var bool: Boolean - -external var str: String - external fun numReferenceFun(): Number external fun boolReferenceFun(): Boolean diff --git a/compiler/test/data/javascript/reference/variable.d.ts b/compiler/test/data/javascript/reference/variable.d.ts index c32cb4aa6..b6536495d 100644 --- a/compiler/test/data/javascript/reference/variable.d.ts +++ b/compiler/test/data/javascript/reference/variable.d.ts @@ -12,4 +12,8 @@ function boolReferenceFun() { function stringReferenceFun() { return str -} \ No newline at end of file +} + +module.exports.numReferenceFun = numReferenceFun +module.exports.boolReferenceFun = boolReferenceFun +module.exports.stringReferenceFun = stringReferenceFun \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index b49e4b114..6be32fe07 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -1,6 +1,9 @@ package org.jetbrains.dukat.js.type.analysis -import org.jetbrains.dukat.js.type.property_owner.Scope +import org.jetbrains.dukat.js.type.export_resolution.CommonJSEnvironmentProvider +import org.jetbrains.dukat.js.type.export_resolution.CommonJSExportResolver +import org.jetbrains.dukat.js.type.export_resolution.EmptyEnvironmentProvider +import org.jetbrains.dukat.js.type.export_resolution.EnvironmentProvider import org.jetbrains.dukat.js.type.export_resolution.GeneralExportResolver import org.jetbrains.dukat.js.type.export_resolution.ExportResolver import org.jetbrains.dukat.panic.raiseConcern @@ -8,20 +11,25 @@ import org.jetbrains.dukat.tsmodel.ModuleDeclaration import org.jetbrains.dukat.tsmodel.SourceFileDeclaration import org.jetbrains.dukat.tsmodel.SourceSetDeclaration -fun ModuleDeclaration.introduceTypes(exportResolver: ExportResolver) : ModuleDeclaration { - val scope = Scope(null) +fun ModuleDeclaration.introduceTypes(environmentProvider: EnvironmentProvider, exportResolver: ExportResolver) : ModuleDeclaration { + val env = environmentProvider.getEnvironment() val pathWalker = PathWalker() - calculateConstraints(scope, pathWalker) + calculateConstraints(env, pathWalker) if (pathWalker.startNextPath()) { //TODO check other paths raiseConcern("Conditional at top level not allowed!") { } } - val declarations = exportResolver.resolve(scope) + val declarations = exportResolver.resolve(env) return copy(declarations = declarations) } -fun SourceFileDeclaration.introduceTypes(exportResolver: ExportResolver) = copy(root = root.introduceTypes(exportResolver)) +fun SourceFileDeclaration.introduceTypes(environmentProvider: EnvironmentProvider, exportResolver: ExportResolver): SourceFileDeclaration { + return copy(root = root.introduceTypes(environmentProvider, exportResolver)) +} -fun SourceSetDeclaration.introduceTypes(exportResolver: ExportResolver = GeneralExportResolver()) = copy(sources = sources.map { it.introduceTypes(exportResolver) }) \ No newline at end of file +fun SourceSetDeclaration.introduceTypes(environmentProvider: EnvironmentProvider = CommonJSEnvironmentProvider(), exportResolver: ExportResolver = CommonJSExportResolver()): SourceSetDeclaration { +//fun SourceSetDeclaration.introduceTypes(environmentProvider: EnvironmentProvider = EmptyEnvironmentProvider(), exportResolver: ExportResolver = GeneralExportResolver()): SourceSetDeclaration { + return copy(sources = sources.map { it.introduceTypes(environmentProvider, exportResolver) }) +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSEnvironmentProvider.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSEnvironmentProvider.kt new file mode 100644 index 000000000..0b0f19c3a --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSEnvironmentProvider.kt @@ -0,0 +1,19 @@ +package org.jetbrains.dukat.js.type.export_resolution + +import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint +import org.jetbrains.dukat.js.type.property_owner.Scope + +class CommonJSEnvironmentProvider : EnvironmentProvider { + override fun getEnvironment(): Scope { + val env = Scope(null) + + val moduleObject = ObjectConstraint(env) + val exportsObject = ObjectConstraint(env) + + moduleObject["exports"] = exportsObject + env["module"] = moduleObject + env["exports"] = exportsObject + + return env + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSExportResolver.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSExportResolver.kt new file mode 100644 index 000000000..e2c1de7a5 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSExportResolver.kt @@ -0,0 +1,35 @@ +package org.jetbrains.dukat.js.type.export_resolution + +import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint +import org.jetbrains.dukat.js.type.property_owner.Scope +import org.jetbrains.dukat.panic.raiseConcern +import org.jetbrains.dukat.tsmodel.TopLevelDeclaration + +class CommonJSExportResolver : ExportResolver { + private val generalExportResolver = GeneralExportResolver() + + override fun resolve(scope: Scope): List { + val moduleObject = scope["module"] + + if (moduleObject is ObjectConstraint) { + val exportsObject = moduleObject["exports"] + + if (exportsObject != null) { + return generalExportResolver.resolve( + Scope(null).apply { + if (exportsObject is ObjectConstraint) { + exportsObject.propertyNames.forEach { + this[it] = exportsObject[it]!! + } + } else { + //TODO figure out what to do in this case + this["default"] = exportsObject + } + } + ) + } + } + + return raiseConcern("No exports found!") { emptyList() } + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EmptyEnvironmentProvider.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EmptyEnvironmentProvider.kt new file mode 100644 index 000000000..8be02e75e --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EmptyEnvironmentProvider.kt @@ -0,0 +1,9 @@ +package org.jetbrains.dukat.js.type.export_resolution + +import org.jetbrains.dukat.js.type.property_owner.Scope + +class EmptyEnvironmentProvider : EnvironmentProvider { + override fun getEnvironment(): Scope { + return Scope(null) + } +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EnvironmentProvider.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EnvironmentProvider.kt new file mode 100644 index 000000000..88271e9f8 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EnvironmentProvider.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.js.type.export_resolution + +import org.jetbrains.dukat.js.type.property_owner.Scope + +interface EnvironmentProvider { + fun getEnvironment(): Scope +} \ No newline at end of file From 00a1e8a7c1f52449db3d124e7b3f9c926fa1488c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Nov 2019 17:52:00 +0100 Subject: [PATCH 088/172] Fix properties being static when they shouldn't be, and the other way around. --- .../test/data/javascript/object/construct.d.kt | 9 +++------ .../test/data/javascript/object/modified.d.kt | 16 +++++----------- .../resolution/constraintToDeclaration.kt | 2 +- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/compiler/test/data/javascript/object/construct.d.kt b/compiler/test/data/javascript/object/construct.d.kt index fd414b5a6..87cd79098 100644 --- a/compiler/test/data/javascript/object/construct.d.kt +++ b/compiler/test/data/javascript/object/construct.d.kt @@ -15,13 +15,10 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") external interface `T$0` { - companion object { - var x: Number - var y: Number - var z: Number - } + var x: Number + var y: Number + var z: Number } external object v { diff --git a/compiler/test/data/javascript/object/modified.d.kt b/compiler/test/data/javascript/object/modified.d.kt index 63bd6ea47..1648495a3 100644 --- a/compiler/test/data/javascript/object/modified.d.kt +++ b/compiler/test/data/javascript/object/modified.d.kt @@ -15,23 +15,17 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") external interface `T$0` { - companion object { - var x: Number - var y: Number - } + var x: Number + var y: Number } external fun get2DVector(): `T$0` -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") external interface `T$1` { - companion object { - var x: Number - var y: Number - var z: Number - } + var x: Number + var y: Number + var z: Number } external fun get3DVector(): `T$1` diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index c6e81501e..276b0ccf6 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -49,7 +49,7 @@ fun getPropertyDeclaration(name: String, type: ParameterValueDeclaration, isStat type = type, typeParameters = emptyList(), optional = false, - modifiers = if (isStatic) emptyList() else STATIC_MODIFIERS + modifiers = if (isStatic) STATIC_MODIFIERS else emptyList() ) fun Constraint.toParameterDeclaration(name: String) = ParameterDeclaration( From 455071b05b1ff1943c2583f3d8843075b1b6e875 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Nov 2019 19:40:11 +0100 Subject: [PATCH 089/172] Minor fixes --- .../src/org/jetbrains/dukat/js/type/analysis/expression.kt | 5 +++-- .../dukat/js/type/constraint/properties/ClassConstraint.kt | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 36e351702..8785ac05d 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -13,6 +13,7 @@ import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint import org.jetbrains.dukat.js.type.constraint.reference.call.CallArgumentConstraint import org.jetbrains.dukat.js.type.constraint.reference.call.CallResultConstraint import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint +import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration @@ -129,14 +130,14 @@ fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: P } fun NewExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { - val classConstraints = expression.calculateConstraints(owner, path) + val classConstraints = expression.calculateConstraints(owner, path) as PropertyOwnerConstraint //TODO add constraints for constructor call arguments.map { it.calculateConstraints(owner, path) } return ObjectConstraint( owner = owner, - instantiatedClass = classConstraints as ClassConstraint + instantiatedClass = classConstraints ) } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt index e46ec173c..10250fce2 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt @@ -3,7 +3,7 @@ package org.jetbrains.dukat.js.type.constraint.properties import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -class ClassConstraint(parent: PropertyOwner, prototype: ObjectConstraint = ObjectConstraint(parent)) : PropertyOwnerConstraint(parent) { +class ClassConstraint(owner: PropertyOwner, prototype: ObjectConstraint = ObjectConstraint(owner)) : PropertyOwnerConstraint(owner) { val propertyNames: Set get() = staticMembers.keys From 2822bc1ce52ef40dd234134831e382421eaacd9d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Nov 2019 10:29:01 +0100 Subject: [PATCH 090/172] Resolve certain constraints only once, and store the result. --- .../properties/FunctionConstraint.kt | 40 ++++++++++++------- .../reference/ReferenceConstraint.kt | 20 +++++++++- .../constraint/resolution/ResolutionState.kt | 7 ++++ 3 files changed, 51 insertions(+), 16 deletions(-) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/ResolutionState.kt diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt index 72091a41a..c991fa3ba 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt @@ -4,28 +4,38 @@ import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.constraint.resolution.ResolutionState class FunctionConstraint( val returnConstraints: Constraint, val parameterConstraints: List> ) : ImmutableConstraint { //TODO make property owner (since functions technically are, in javascript) - private var isResolving = false + private var resolutionState = ResolutionState.UNRESOLVED + private var resolvedConstraint: FunctionConstraint? = null override fun resolve(): FunctionConstraint { - return if (!isResolving) { - isResolving = true - val resolvedConstraint = FunctionConstraint( - returnConstraints.resolve(), - parameterConstraints.map { (name, constraint) -> name to constraint.resolve() } - ) - isResolving = false - resolvedConstraint - } else { - FunctionConstraint( - RecursiveConstraint, - parameterConstraints.map { (name, _) -> name to NoTypeConstraint } - ) + return when (resolutionState) { + ResolutionState.UNRESOLVED -> { + resolutionState = ResolutionState.RESOLVING + resolvedConstraint = FunctionConstraint( + returnConstraints.resolve(), + parameterConstraints.map { (name, constraint) -> name to constraint.resolve() } + ) + resolutionState = ResolutionState.RESOLVED + + resolvedConstraint!! + } + + ResolutionState.RESOLVING -> { + FunctionConstraint( + RecursiveConstraint, + parameterConstraints.map { (name, _) -> name to NoTypeConstraint } + ) + } + + ResolutionState.RESOLVED -> { + resolvedConstraint!! + } } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt index 0e281d0c4..7e9070422 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt @@ -3,6 +3,7 @@ package org.jetbrains.dukat.js.type.constraint.reference import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.constraint.resolution.ResolutionState import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.panic.raiseConcern @@ -10,6 +11,9 @@ open class ReferenceConstraint( private val identifier: IdentifierEntity, owner: PropertyOwner ) : PropertyOwnerReferenceConstraint(owner) { + private var resolutionState = ResolutionState.UNRESOLVED + private var resolvedConstraint: Constraint? = null + private tailrec fun resolveInOwner(owner: PropertyOwner): Constraint? { val resolvedOwner = if(owner is Constraint) { val resolvedConstraint = owner.resolve() @@ -41,6 +45,20 @@ open class ReferenceConstraint( } override fun resolve(): Constraint { - return resolveInOwner(owner) ?: CompositeConstraint() + return when (resolutionState) { + ResolutionState.UNRESOLVED -> { + resolvedConstraint = resolveInOwner(owner) ?: CompositeConstraint() + resolutionState = ResolutionState.RESOLVED + return resolvedConstraint!! + } + + ResolutionState.RESOLVING -> { + raiseConcern("Invalid converter state!") { CompositeConstraint() } + } + + ResolutionState.RESOLVED -> { + resolvedConstraint!! + } + } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/ResolutionState.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/ResolutionState.kt new file mode 100644 index 000000000..673cbd39e --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/ResolutionState.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.js.type.constraint.resolution + +internal enum class ResolutionState { + UNRESOLVED, + RESOLVING, + RESOLVED +} \ No newline at end of file From cbd30dd85619ef38eba55245d284971e615eadc1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Nov 2019 10:30:52 +0100 Subject: [PATCH 091/172] Fix out of bounds error, when evaluating function call with more arguments then explicitely specified --- .../js/type/constraint/reference/call/CallArgumentConstraint.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt index 55dd328ac..c3bba948f 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt @@ -13,7 +13,7 @@ class CallArgumentConstraint( val functionConstraint = callTarget.resolve() return if (functionConstraint is FunctionConstraint) { - if (functionConstraint.parameterConstraints.size >= argumentNum) { + if (functionConstraint.parameterConstraints.size > argumentNum) { functionConstraint.parameterConstraints[argumentNum].second } else { CompositeConstraint() From 62041755dd4755320958ad21e54cf5f00b91cf51 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Nov 2019 12:11:44 +0100 Subject: [PATCH 092/172] Add function and class expressions --- typescript/ts-converter/src/AstConverter.ts | 8 +-- .../src/ast/AstExpressionConverter.ts | 58 ++++++++++++++++--- .../src/ast/AstExpressionFactory.ts | 15 ++++- typescript/ts-converter/src/ast/AstFactory.ts | 9 ++- .../ts-model-proto/src/Declarations.proto | 18 +++--- .../dukat/tsmodel/ClassDeclaration.kt | 2 +- .../dukat/tsmodel/FunctionDeclaration.kt | 2 +- .../dukat/tsmodel/factory/convertProtobuf.kt | 2 + 8 files changed, 89 insertions(+), 25 deletions(-) diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index a33005f23..820dae479 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -5,7 +5,6 @@ import {createLogger} from "./Logger"; import {uid} from "./uid"; import { Block, - ClassDeclaration, Declaration, DefinitionInfoDeclaration, Expression, @@ -31,8 +30,6 @@ export class AstConverter { private log = createLogger("AstConverter"); private unsupportedDeclarations = new Set(); - private astExpressionConverter = new AstExpressionConverter(this); - constructor( private rootPackageName: NameEntity, private resources: ResourceFetcher, @@ -44,6 +41,9 @@ export class AstConverter { ) { } + private astExpressionConverter = new AstExpressionConverter(this, this.astFactory); + + private registerDeclaration(declaration: T, collection: Array) { collection.push(declaration); } @@ -710,7 +710,7 @@ export class AstConverter { return null; } - return this.astFactory.createClassDeclaration( + return this.astFactory.createClassDeclarationAsTopLevel( this.astFactory.createIdentifierDeclarationAsNameEntity(statement.name.getText()), this.convertClassElementsToMembers(statement.members), this.convertTypeParams(statement.typeParameters), diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index 7a53e384d..c98e84cd7 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -1,20 +1,19 @@ import * as ts from "typescript-services-api"; import { - Declaration, - Expression, - FunctionDeclaration, + Block, + Expression, HeritageClauseDeclaration, IdentifierDeclaration, - MemberDeclaration, - NameEntity, - PropertyDeclaration + MemberDeclaration, ModifierDeclaration, + NameEntity, ParameterDeclaration, TypeDeclaration, TypeParameter, } from "./ast"; import {AstExpressionFactory} from "./AstExpressionFactory"; import {AstConverter} from "../AstConverter"; -import {ObjectLiteralElementLike} from "../../.tsdeclarations/typescript"; +import {AstFactory} from "./AstFactory"; export class AstExpressionConverter { constructor( - private astConverter: AstConverter + private astConverter: AstConverter, + private astFactory: AstFactory ) { } @@ -26,6 +25,14 @@ export class AstExpressionConverter { return AstExpressionFactory.createUnaryExpressionDeclarationAsExpression(operand, operator, isPrefix); } + createFunctionExpression(name: string, parameters: Array, type: TypeDeclaration, typeParams: Array, modifiers: Array, body: Block | null) { + return AstExpressionFactory.convertFunctionDeclarationToExpression(this.astFactory.createFunctionDeclaration(name, parameters, type, typeParams, modifiers, body, "__NO_UID__")); + } + + createClassExpression(name: NameEntity, members: Array, typeParams: Array, parentEntities: Array, modifiers: Array) { + return AstExpressionFactory.convertClassDeclarationToExpression(this.astFactory.createClassDeclaration(name, members, typeParams, parentEntities, modifiers, "__NO_UID__")); + } + createTypeOfExpression(expression: Expression) { return AstExpressionFactory.createTypeOfExpressionDeclarationAsExpression(expression); } @@ -103,6 +110,37 @@ export class AstExpressionConverter { ) } + convertFunctionExpression(expression: ts.FunctionExpression): Expression { + let name = expression.name ? expression.name.getText() : ""; + + let parameterDeclarations = expression.parameters.map( + (param, count) => this.astConverter.convertParameterDeclaration(param, count) + ); + + let returnType = expression.type ? this.astConverter.convertType(expression.type) : this.astConverter.createTypeDeclaration("Unit"); + + let typeParameterDeclarations = this.astConverter.convertTypeParams(expression.typeParameters); + + return this.createFunctionExpression( + name, + parameterDeclarations, + returnType, + typeParameterDeclarations, + this.astConverter.convertModifiers(expression.modifiers), + this.astConverter.convertBlock(expression.body) + ) + } + + convertClassExpression(expression: ts.ClassExpression): Expression { + return this.createClassExpression( + this.astFactory.createIdentifierDeclarationAsNameEntity(""), + this.astConverter.convertClassElementsToMembers(expression.members), + this.astConverter.convertTypeParams(expression.typeParameters), + this.astConverter.convertHeritageClauses(expression.heritageClauses), + this.astConverter.convertModifiers(expression.modifiers) + ); + } + convertTypeOfExpression(expression: ts.TypeOfExpression): Expression { return this.createTypeOfExpression( this.convertExpression(expression.expression), @@ -269,6 +307,10 @@ export class AstExpressionConverter { return this.convertPrefixUnaryExpression(expression) } else if (ts.isPostfixUnaryExpression(expression)) { return this.convertPostfixUnaryExpression(expression) + } else if (ts.isFunctionExpression(expression)) { + return this.convertFunctionExpression(expression) + } else if (ts.isClassExpression(expression)) { + return this.convertClassExpression(expression) } else if (ts.isTypeOfExpression(expression)) { return this.convertTypeOfExpression(expression); } else if (ts.isCallExpression(expression)) { diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index 6eb276957..a5c5eab99 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -1,6 +1,7 @@ import * as declarations from "declarations"; import { - Expression, + ClassDeclaration, + Expression, FunctionDeclaration, IdentifierDeclaration, LiteralExpression, MemberDeclaration, @@ -125,6 +126,18 @@ export class AstExpressionFactory { return expression; } + static convertFunctionDeclarationToExpression(functionExpression: FunctionDeclaration): Expression { + let expression = new declarations.ExpressionDeclarationProto(); + expression.setFunctionexpression(functionExpression); + return expression; + } + + static convertClassDeclarationToExpression(classExpression: ClassDeclaration): Expression { + let expression = new declarations.ExpressionDeclarationProto(); + expression.setClassexpression(classExpression); + return expression; + } + static createNumericLiteralDeclarationAsExpression(value: string): Expression { let numericLiteralExpression = new declarations.NumericLiteralExpressionDeclarationProto(); numericLiteralExpression.setValue(value); diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index 1b15fa543..55b5d119c 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -49,7 +49,7 @@ export class AstFactory implements AstFactory { return memberProto; } - createClassDeclaration(name: NameEntity, members: Array, typeParams: Array, parentEntities: Array, modifiers: Array, uid: string): Declaration { + createClassDeclaration(name: NameEntity, members: Array, typeParams: Array, parentEntities: Array, modifiers: Array, uid: string): ClassDeclaration { let classDeclaration = new declarations.ClassDeclarationProto(); classDeclaration.setName(name); classDeclaration.setModifiersList(modifiers); @@ -57,6 +57,11 @@ export class AstFactory implements AstFactory { classDeclaration.setMembersList(members); classDeclaration.setTypeparametersList(typeParams); classDeclaration.setParententitiesList(parentEntities); + return classDeclaration + } + + createClassDeclarationAsTopLevel(name: NameEntity, members: Array, typeParams: Array, parentEntities: Array, modifiers: Array, uid: string): Declaration { + let classDeclaration = this.createClassDeclaration(name, members, typeParams, parentEntities, modifiers, uid); let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); topLevelDeclaration.setClassdeclaration(classDeclaration); @@ -166,7 +171,7 @@ export class AstFactory implements AstFactory { return topLevelDeclaration; } - private createFunctionDeclaration(name: string, parameters: Array, type: TypeDeclaration, typeParams: Array, modifiers: Array, body: Block | null, uid: string): FunctionDeclaration { + createFunctionDeclaration(name: string, parameters: Array, type: TypeDeclaration, typeParams: Array, modifiers: Array, body: Block | null, uid: string): FunctionDeclaration { let functionDeclaration = new declarations.FunctionDeclarationProto(); functionDeclaration.setName(name); functionDeclaration.setParametersList(parameters); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 62c3f1537..6032a6cf5 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -244,14 +244,16 @@ message ExpressionDeclarationProto { oneof type { BinaryExpressionDeclarationProto binaryExpression = 1; UnaryExpressionDeclarationProto unaryExpression = 2; - TypeOfExpressionDeclarationProto typeOfExpression = 3; - CallExpressionDeclarationProto callExpression = 4; - NameExpressionDeclarationProto nameExpression = 5; - LiteralExpressionDeclarationProto literalExpression = 6; - PropertyAccessExpressionDeclarationProto propertyAccessExpression = 7; - ElementAccessExpressionDeclarationProto elementAccessExpression = 8; - NewExpressionDeclarationProto newExpression = 9; - UnknownExpressionDeclarationProto unknownExpression = 10; + FunctionDeclarationProto functionExpression = 3; + ClassDeclarationProto classExpression = 4; + TypeOfExpressionDeclarationProto typeOfExpression = 5; + CallExpressionDeclarationProto callExpression = 6; + NameExpressionDeclarationProto nameExpression = 7; + LiteralExpressionDeclarationProto literalExpression = 8; + PropertyAccessExpressionDeclarationProto propertyAccessExpression = 9; + ElementAccessExpressionDeclarationProto elementAccessExpression = 10; + NewExpressionDeclarationProto newExpression = 11; + UnknownExpressionDeclarationProto unknownExpression = 12; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ClassDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ClassDeclaration.kt index f8a57e6cb..ef3fb1deb 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ClassDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ClassDeclaration.kt @@ -9,4 +9,4 @@ data class ClassDeclaration( override val parentEntities: List, val modifiers: List, override val uid: String -) : ClassLikeDeclaration +) : ClassLikeDeclaration, ExpressionDeclaration diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt index a7d863d78..679e1fbbe 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt @@ -10,4 +10,4 @@ data class FunctionDeclaration( val modifiers: List, val body: BlockDeclaration?, override val uid: String -) : MemberDeclaration, TopLevelDeclaration, WithUidDeclaration, ParameterOwnerDeclaration \ No newline at end of file +) : MemberDeclaration, TopLevelDeclaration, WithUidDeclaration, ParameterOwnerDeclaration, ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index dcb6dc2b7..27f023657 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -517,6 +517,8 @@ fun ExpressionDeclarationProto.convert() : ExpressionDeclaration { return when { hasBinaryExpression() -> binaryExpression.convert() hasUnaryExpression() -> unaryExpression.convert() + hasFunctionExpression() -> functionExpression.convert() + hasClassExpression() -> classExpression.convert() hasTypeOfExpression() -> typeOfExpression.convert() hasCallExpression() -> callExpression.convert() hasNameExpression() -> nameExpression.convert() From 4fe3035950fa518b3b22357df71c813ddbdaf334 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Nov 2019 13:04:46 +0100 Subject: [PATCH 093/172] Support function and class expressions --- .../js/type/analysis/calculateConstraints.kt | 101 ------------------ .../dukat/js/type/analysis/expression.kt | 91 ++++++++++++++++ .../dukat/js/type/analysis/members.kt | 47 ++++++++ 3 files changed, 138 insertions(+), 101 deletions(-) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt index a2a027cde..e88fef56c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt @@ -28,107 +28,6 @@ import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.WhileStatementDeclaration -fun List.pack() : FunctionConstraint { - return if (size == 1) { - this[0] - } else { - val parameters = mutableListOf>>() - - forEach { - it.parameterConstraints.forEachIndexed { index, (name, constraint) -> - if (parameters.size <= index) { - parameters.add(index, name to mutableListOf()) - } - - parameters[index].second.add(constraint) - } - } - - FunctionConstraint( - returnConstraints = UnionTypeConstraint(map { it.returnConstraints }), - parameterConstraints = parameters.map { (name, constraints) -> name to UnionTypeConstraint(constraints) } - ) - } -} - -fun FunctionDeclaration.addTo(owner: PropertyOwner) { - if (this.body != null) { - val pathWalker = PathWalker() - - val versions = mutableListOf() - - do { - val functionScope = Scope(owner) - - val parameterConstraints = MutableList(parameters.size) { i -> - // Store constraints of parameters in scope, - // and in parameter list (in case the variable is replaced) - val parameterConstraint = CompositeConstraint() - functionScope[parameters[i].name] = parameterConstraint - parameters[i].name to parameterConstraint - } - - val returnTypeConstraints = body!!.calculateConstraints(functionScope, pathWalker) ?: VoidTypeConstraint - - versions.add(FunctionConstraint( - returnConstraints = returnTypeConstraints, - parameterConstraints = parameterConstraints - )) - } while (pathWalker.startNextPath()) - - owner[name] = versions.pack() - } -} - -@Suppress("UNUSED") -fun ConstructorDeclaration.addTo(@Suppress("UNUSED_PARAMETER") owner: PropertyOwner) { - raiseConcern("Cannot create header for constructor.") { } //TODO add constructor body to AST -} - -fun PropertyDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { - owner[name] = initializer?.calculateConstraints(owner, path) ?: NoTypeConstraint -} - -fun MemberDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { - when (this) { - is FunctionDeclaration -> this.addTo(owner) - is PropertyDeclaration -> this.addTo(owner, path) - else -> raiseConcern("Unexpected member entity type <${this::class}> in object.") { this } - } -} - -fun MemberDeclaration.addToClass(owner: ClassConstraint, path: PathWalker) { - when (this) { - is ConstructorDeclaration -> this.addTo(owner) - is FunctionDeclaration -> if (this.modifiers.contains(ModifierDeclaration.STATIC_KEYWORD)) { - this.addTo(owner) - } else { - val ownerPrototype = owner["prototype"] - - if (ownerPrototype is PropertyOwner) { - this.addTo(ownerPrototype) - } else { - raiseConcern("Class prototype corrupt! Cannot add members.") { } - } - } - is PropertyDeclaration -> this.addTo(owner, path) - else -> raiseConcern("Unexpected member entity type <${this::class}> in class.") { this } - } -} - -fun ClassDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { - val className = name // Needed for smart cast - if(className is IdentifierEntity) { - val classConstraint = ClassConstraint(owner) - - members.forEach { it.addToClass(classConstraint, path) } - - owner[className.value] = classConstraint - } else { - raiseConcern("Cannot convert class with name of type <${className::class}>.") { } - } -} - fun BlockDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { return statements.calculateConstraints(owner, path) } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 8785ac05d..46ee04a12 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -1,21 +1,32 @@ package org.jetbrains.dukat.js.type.analysis +import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.reference.ReferenceConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint +import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.constraint.reference.call.CallArgumentConstraint import org.jetbrains.dukat.js.type.constraint.reference.call.CallResultConstraint import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint +import org.jetbrains.dukat.js.type.property_owner.Scope import org.jetbrains.dukat.panic.raiseConcern +import org.jetbrains.dukat.tsmodel.ClassDeclaration +import org.jetbrains.dukat.tsmodel.ConstructorDeclaration import org.jetbrains.dukat.tsmodel.ExpressionDeclaration +import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.MemberDeclaration +import org.jetbrains.dukat.tsmodel.ModifierDeclaration +import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.CallExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.NewExpressionDeclaration @@ -30,6 +41,84 @@ import org.jetbrains.dukat.tsmodel.expression.literal.ObjectLiteralExpressionDec import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration +fun List.pack() : FunctionConstraint { + return if (size == 1) { + this[0] + } else { + val parameters = mutableListOf>>() + + forEach { + it.parameterConstraints.forEachIndexed { index, (name, constraint) -> + if (parameters.size <= index) { + parameters.add(index, name to mutableListOf()) + } + + parameters[index].second.add(constraint) + } + } + + FunctionConstraint( + returnConstraints = UnionTypeConstraint(map { it.returnConstraints }), + parameterConstraints = parameters.map { (name, constraints) -> name to UnionTypeConstraint(constraints) } + ) + } +} + +fun FunctionDeclaration.addTo(owner: PropertyOwner) : FunctionConstraint? { + return if (this.body != null) { + val pathWalker = PathWalker() + + val versions = mutableListOf() + + do { + val functionScope = Scope(owner) + + val parameterConstraints = MutableList(parameters.size) { i -> + // Store constraints of parameters in scope, + // and in parameter list (in case the variable is replaced) + val parameterConstraint = CompositeConstraint() + functionScope[parameters[i].name] = parameterConstraint + parameters[i].name to parameterConstraint + } + + val returnTypeConstraints = body!!.calculateConstraints(functionScope, pathWalker) ?: VoidTypeConstraint + + versions.add(FunctionConstraint( + returnConstraints = returnTypeConstraints, + parameterConstraints = parameterConstraints + )) + } while (pathWalker.startNextPath()) + + val functionConstraint = versions.pack() + + if (name != "") { + owner[name] = functionConstraint + } + + functionConstraint + } else { + null + } +} + +fun ClassDeclaration.addTo(owner: PropertyOwner, path: PathWalker) : ClassConstraint? { + val className = name // Needed for smart cast + return if(className is IdentifierEntity) { + val classConstraint = ClassConstraint(owner) + + members.forEach { it.addToClass(classConstraint, path) } + + if (className.value != "") { + owner[className.value] = classConstraint + } + + classConstraint + } else { + raiseConcern("Cannot convert class with name of type <${className::class}>.") { null } + } +} + + fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { return when (operator) { // Assignments @@ -160,6 +249,8 @@ fun LiteralExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path fun ExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { return when (this) { + is FunctionDeclaration -> this.addTo(owner) ?: NoTypeConstraint + is ClassDeclaration -> this.addTo(owner, path) ?: NoTypeConstraint is IdentifierExpressionDeclaration -> owner[this] ?: ReferenceConstraint(this.identifier, owner) is PropertyAccessExpressionDeclaration -> owner[this, path] ?: CompositeConstraint() //TODO replace this with a reference constraint (of some sort) is BinaryExpressionDeclaration -> this.calculateConstraints(owner, path) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt new file mode 100644 index 000000000..23f44a4c1 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt @@ -0,0 +1,47 @@ +package org.jetbrains.dukat.js.type.analysis + +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint +import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.panic.raiseConcern +import org.jetbrains.dukat.tsmodel.ConstructorDeclaration +import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.MemberDeclaration +import org.jetbrains.dukat.tsmodel.ModifierDeclaration +import org.jetbrains.dukat.tsmodel.PropertyDeclaration + +@Suppress("UNUSED") +fun ConstructorDeclaration.addTo(@Suppress("UNUSED_PARAMETER") owner: PropertyOwner) { + raiseConcern("Cannot create header for constructor.") { } //TODO add constructor body to AST +} + +fun PropertyDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { + owner[name] = initializer?.calculateConstraints(owner, path) ?: NoTypeConstraint +} + +fun MemberDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { + when (this) { + is FunctionDeclaration -> this.addTo(owner) + is PropertyDeclaration -> this.addTo(owner, path) + else -> raiseConcern("Unexpected member entity type <${this::class}> in object.") { this } + } +} + +fun MemberDeclaration.addToClass(owner: ClassConstraint, path: PathWalker) { + when (this) { + is ConstructorDeclaration -> this.addTo(owner) + is FunctionDeclaration -> if (this.modifiers.contains(ModifierDeclaration.STATIC_KEYWORD)) { + this.addTo(owner) + } else { + val ownerPrototype = owner["prototype"] + + if (ownerPrototype is PropertyOwner) { + this.addTo(ownerPrototype) + } else { + raiseConcern("Class prototype corrupt! Cannot add members.") { } + } + } + is PropertyDeclaration -> this.addTo(owner, path) + else -> raiseConcern("Unexpected member entity type <${this::class}> in class.") { this } + } +} \ No newline at end of file From a067daa597a8088e3cd31be04be26814f44392ed Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Nov 2019 13:16:34 +0100 Subject: [PATCH 094/172] Build CommonJS environment on top of default environment --- .../js/type/export_resolution/CommonJSEnvironmentProvider.kt | 2 +- ...mptyEnvironmentProvider.kt => DefaultEnvironmentProvider.kt} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/{EmptyEnvironmentProvider.kt => DefaultEnvironmentProvider.kt} (76%) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSEnvironmentProvider.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSEnvironmentProvider.kt index 0b0f19c3a..77ae7acb1 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSEnvironmentProvider.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSEnvironmentProvider.kt @@ -5,7 +5,7 @@ import org.jetbrains.dukat.js.type.property_owner.Scope class CommonJSEnvironmentProvider : EnvironmentProvider { override fun getEnvironment(): Scope { - val env = Scope(null) + val env = DefaultEnvironmentProvider().getEnvironment() val moduleObject = ObjectConstraint(env) val exportsObject = ObjectConstraint(env) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EmptyEnvironmentProvider.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/DefaultEnvironmentProvider.kt similarity index 76% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EmptyEnvironmentProvider.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/DefaultEnvironmentProvider.kt index 8be02e75e..543aac081 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EmptyEnvironmentProvider.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/DefaultEnvironmentProvider.kt @@ -2,7 +2,7 @@ package org.jetbrains.dukat.js.type.export_resolution import org.jetbrains.dukat.js.type.property_owner.Scope -class EmptyEnvironmentProvider : EnvironmentProvider { +class DefaultEnvironmentProvider : EnvironmentProvider { override fun getEnvironment(): Scope { return Scope(null) } From 1c289cf3e19dfbfe504b7a829ca29ce2f0c00bef Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Nov 2019 13:17:13 +0100 Subject: [PATCH 095/172] Remove unneeded imports --- .../dukat/js/type/analysis/calculateConstraints.kt | 10 ---------- .../jetbrains/dukat/js/type/analysis/introduceTypes.kt | 2 -- 2 files changed, 12 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt index e88fef56c..d18f6deec 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt @@ -1,28 +1,18 @@ package org.jetbrains.dukat.js.type.analysis -import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint -import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint -import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint -import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -import org.jetbrains.dukat.js.type.property_owner.Scope import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.BlockDeclaration import org.jetbrains.dukat.tsmodel.ClassDeclaration -import org.jetbrains.dukat.tsmodel.ConstructorDeclaration import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.IfStatementDeclaration import org.jetbrains.dukat.tsmodel.InterfaceDeclaration -import org.jetbrains.dukat.tsmodel.MemberDeclaration -import org.jetbrains.dukat.tsmodel.ModifierDeclaration import org.jetbrains.dukat.tsmodel.ModuleDeclaration -import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index 6be32fe07..eddc146b2 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -2,9 +2,7 @@ package org.jetbrains.dukat.js.type.analysis import org.jetbrains.dukat.js.type.export_resolution.CommonJSEnvironmentProvider import org.jetbrains.dukat.js.type.export_resolution.CommonJSExportResolver -import org.jetbrains.dukat.js.type.export_resolution.EmptyEnvironmentProvider import org.jetbrains.dukat.js.type.export_resolution.EnvironmentProvider -import org.jetbrains.dukat.js.type.export_resolution.GeneralExportResolver import org.jetbrains.dukat.js.type.export_resolution.ExportResolver import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ModuleDeclaration From d2ca1649f81a1b3cd5ed7414248d0f6616743314 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Nov 2019 13:33:37 +0100 Subject: [PATCH 096/172] Remove unneeded dead code --- .../src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index eddc146b2..5171ffd06 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -28,6 +28,5 @@ fun SourceFileDeclaration.introduceTypes(environmentProvider: EnvironmentProvide } fun SourceSetDeclaration.introduceTypes(environmentProvider: EnvironmentProvider = CommonJSEnvironmentProvider(), exportResolver: ExportResolver = CommonJSExportResolver()): SourceSetDeclaration { -//fun SourceSetDeclaration.introduceTypes(environmentProvider: EnvironmentProvider = EmptyEnvironmentProvider(), exportResolver: ExportResolver = GeneralExportResolver()): SourceSetDeclaration { return copy(sources = sources.map { it.introduceTypes(environmentProvider, exportResolver) }) } \ No newline at end of file From cd40b8fb13439a6947a9eaa6d28e9dbf6fbd0575 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Nov 2019 13:38:17 +0100 Subject: [PATCH 097/172] Fix crash when converting 'new' expression without argument block for constructor --- typescript/ts-converter/src/ast/AstExpressionConverter.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index c98e84cd7..1b3aa636f 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -171,7 +171,8 @@ export class AstExpressionConverter { convertNewExpression(expression: ts.NewExpression): Expression { return this.createNewExpression( this.convertExpression(expression.expression), - expression.arguments.map(arg => this.convertExpression(arg)) + expression.arguments ? + expression.arguments.map(arg => this.convertExpression(arg)) : [] ) } From 273eb02f407ec383a23b01e0be3d829e3b911557 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Nov 2019 16:45:57 +0100 Subject: [PATCH 098/172] Treat prototype functions as classes --- .../dukat/js/type/analysis/expression.kt | 2 + .../properties/FunctionConstraint.kt | 55 ++++++++++++++++--- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 46ee04a12..1944cdd10 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -58,6 +58,7 @@ fun List.pack() : FunctionConstraint { } FunctionConstraint( + this[0].owner, returnConstraints = UnionTypeConstraint(map { it.returnConstraints }), parameterConstraints = parameters.map { (name, constraints) -> name to UnionTypeConstraint(constraints) } ) @@ -84,6 +85,7 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) : FunctionConstraint? { val returnTypeConstraints = body!!.calculateConstraints(functionScope, pathWalker) ?: VoidTypeConstraint versions.add(FunctionConstraint( + owner, returnConstraints = returnTypeConstraints, parameterConstraints = parameterConstraints )) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt index c991fa3ba..8bb2e456b 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt @@ -1,26 +1,64 @@ package org.jetbrains.dukat.js.type.constraint.properties import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint import org.jetbrains.dukat.js.type.constraint.resolution.ResolutionState +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class FunctionConstraint( + owner: PropertyOwner, val returnConstraints: Constraint, val parameterConstraints: List> -) : ImmutableConstraint { //TODO make property owner (since functions technically are, in javascript) +) : PropertyOwnerConstraint(owner) { + private val classRepresentation = ClassConstraint(owner) + + override fun set(name: String, data: Constraint) { + classRepresentation[name] = data + } + + override fun get(name: String): Constraint? { + return classRepresentation[name] + } + + private var resolutionState = ResolutionState.UNRESOLVED - private var resolvedConstraint: FunctionConstraint? = null + private var resolvedConstraint: Constraint? = null + + private fun isPrototypeFunction() : Boolean { + val onlyHasPrototype = classRepresentation.propertyNames.size == 1 && classRepresentation.propertyNames.contains("prototype") + + return if (onlyHasPrototype) { + val resolvedPrototype = classRepresentation["prototype"]!!.resolve() - override fun resolve(): FunctionConstraint { + if (resolvedPrototype is ObjectConstraint) { + resolvedPrototype.propertyNames.isNotEmpty() + } else { + false + } + } else { + true + } + } + + private fun doResolve(): Constraint { + return if (!isPrototypeFunction()) { + FunctionConstraint( + owner, + returnConstraints.resolve(), + parameterConstraints.map { (name, constraint) -> name to constraint.resolve() } + ) + } else { + //TODO add function as constructor, and invocable + return classRepresentation.resolve() + } + } + + override fun resolve(): Constraint { return when (resolutionState) { ResolutionState.UNRESOLVED -> { resolutionState = ResolutionState.RESOLVING - resolvedConstraint = FunctionConstraint( - returnConstraints.resolve(), - parameterConstraints.map { (name, constraint) -> name to constraint.resolve() } - ) + resolvedConstraint = doResolve() resolutionState = ResolutionState.RESOLVED resolvedConstraint!! @@ -28,6 +66,7 @@ class FunctionConstraint( ResolutionState.RESOLVING -> { FunctionConstraint( + owner, RecursiveConstraint, parameterConstraints.map { (name, _) -> name to NoTypeConstraint } ) From a070f87834e8835de131bf35647956c78680497d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Nov 2019 17:06:55 +0100 Subject: [PATCH 099/172] Add constructor body --- typescript/ts-converter/src/AstConverter.ts | 12 ++++++++---- typescript/ts-converter/src/ast/AstFactory.ts | 5 ++++- typescript/ts-model-proto/src/Declarations.proto | 1 + .../dukat/tsmodel/ConstructorDeclaration.kt | 3 ++- .../dukat/tsmodel/factory/convertProtobuf.kt | 5 ++++- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index 820dae479..2c70105b3 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -615,10 +615,14 @@ export class AstConverter { this.registerDeclaration(this.convertParameterDeclaration(parameter, count), params); }); - this.registerDeclaration(this.astFactory.createConstructorDeclaration( - params, - this.convertTypeParams(constructorDeclaration.typeParameters), this.convertModifiers(constructorDeclaration.modifiers)), - res + this.registerDeclaration( + this.astFactory.createConstructorDeclaration( + params, + this.convertTypeParams(constructorDeclaration.typeParameters), + this.convertModifiers(constructorDeclaration.modifiers), + this.convertBlock(constructorDeclaration.body) + ), + res ); return res; diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index 55b5d119c..8a5705db4 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -68,12 +68,15 @@ export class AstFactory implements AstFactory { return topLevelDeclaration; } - createConstructorDeclaration(parameters: Array, typeParams: Array, modifiers: Array): MemberDeclaration { + createConstructorDeclaration(parameters: Array, typeParams: Array, modifiers: Array, body: Block | null): MemberDeclaration { let constructorDeclaration = new declarations.ConstructorDeclarationProto(); constructorDeclaration.setParametersList(parameters); constructorDeclaration.setTypeparametersList(typeParams); constructorDeclaration.setModifiersList(modifiers); + if (body) { + constructorDeclaration.setBody(body) + } let memberProto = new declarations.MemberDeclarationProto(); memberProto.setConstructordeclaration(constructorDeclaration); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 6032a6cf5..f24ab4324 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -98,6 +98,7 @@ message ConstructorDeclarationProto { repeated ParameterDeclarationProto parameters = 1; repeated TypeParameterDeclarationProto typeParameters = 2; repeated ModifierDeclarationProto modifiers = 3; + BlockDeclarationProto body = 6; } message BlockDeclarationProto { diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ConstructorDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ConstructorDeclaration.kt index 0a6bf1e5e..57a60a61d 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ConstructorDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ConstructorDeclaration.kt @@ -3,5 +3,6 @@ package org.jetbrains.dukat.tsmodel data class ConstructorDeclaration( val parameters: List, val typeParameters: List, - val modifiers: List + val modifiers: List, + val body: BlockDeclaration? ) : MemberDeclaration, ParameterOwnerDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 27f023657..1ecf67d80 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -346,7 +346,10 @@ fun ConstructorDeclarationProto.convert(): ConstructorDeclaration { return ConstructorDeclaration( parametersList.map { it.convert() }, typeParametersList.map { it.convert() }, - modifiersList.map { it.convert() } + modifiersList.map { it.convert() }, + if (hasBody()) { + body.convert() + } else null ) } From b9c1ede87ae7d1ba38e37adec84506fc7d020b65 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Nov 2019 11:18:08 +0100 Subject: [PATCH 100/172] Handle constructor for prototype functions, and make functions with properties into invocable objects --- .../dukat/js/type/analysis/members.kt | 18 +++++- .../constraint/properties/ClassConstraint.kt | 11 +++- .../properties/FunctionConstraint.kt | 57 ++++++++++++++++--- .../constraint/properties/ObjectConstraint.kt | 7 +++ .../resolution/constraintToDeclaration.kt | 28 ++++++++- 5 files changed, 106 insertions(+), 15 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt index 23f44a4c1..2f7f8e4fa 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt @@ -1,5 +1,6 @@ package org.jetbrains.dukat.js.type.analysis +import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner @@ -9,10 +10,21 @@ import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.MemberDeclaration import org.jetbrains.dukat.tsmodel.ModifierDeclaration import org.jetbrains.dukat.tsmodel.PropertyDeclaration +import org.jetbrains.dukat.tsmodel.types.TypeDeclaration -@Suppress("UNUSED") -fun ConstructorDeclaration.addTo(@Suppress("UNUSED_PARAMETER") owner: PropertyOwner) { - raiseConcern("Cannot create header for constructor.") { } //TODO add constructor body to AST +fun ConstructorDeclaration.addTo(owner: ClassConstraint) { + owner.constructorConstraint = FunctionDeclaration( + name = "", + parameters = parameters, + type = TypeDeclaration( + value = IdentifierEntity("Unit"), + params = emptyList() + ), + typeParameters = typeParameters, + modifiers = modifiers, + body = body, + uid = "__NO_UID__" + ).addTo(owner) } fun PropertyDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt index 10250fce2..ba3464056 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt @@ -7,6 +7,8 @@ class ClassConstraint(owner: PropertyOwner, prototype: ObjectConstraint = Object val propertyNames: Set get() = staticMembers.keys + var constructorConstraint: Constraint? = null + private val staticMembers = LinkedHashMap() init { @@ -22,12 +24,15 @@ class ClassConstraint(owner: PropertyOwner, prototype: ObjectConstraint = Object } override fun resolve(): ClassConstraint { - val resolvedConstraint = ClassConstraint(owner) + val constructorConstraint = constructorConstraint + if (constructorConstraint != null) { + this.constructorConstraint = constructorConstraint.resolve() + } propertyNames.forEach { - resolvedConstraint[it] = this[it]!!.resolve() + this[it] = this[it]!!.resolve() } - return resolvedConstraint + return this } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt index 8bb2e456b..83ceb0832 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt @@ -25,11 +25,29 @@ class FunctionConstraint( private var resolutionState = ResolutionState.UNRESOLVED private var resolvedConstraint: Constraint? = null - private fun isPrototypeFunction() : Boolean { - val onlyHasPrototype = classRepresentation.propertyNames.size == 1 && classRepresentation.propertyNames.contains("prototype") + private fun hasMembers() : Boolean { + return if (classRepresentation.propertyNames.isNotEmpty()) { + if (classRepresentation.propertyNames == setOf("prototype")) { + val resolvedPrototype = classRepresentation["prototype"]!!.resolve() - return if (onlyHasPrototype) { - val resolvedPrototype = classRepresentation["prototype"]!!.resolve() + if (resolvedPrototype is ObjectConstraint) { + resolvedPrototype.propertyNames.isNotEmpty() + } else { + false + } + } else { + true + } + } else { + false + } + } + + private fun hasNonStaticMembers() : Boolean { + val prototype = classRepresentation["prototype"] + + return if (prototype != null) { + val resolvedPrototype = prototype.resolve() if (resolvedPrototype is ObjectConstraint) { resolvedPrototype.propertyNames.isNotEmpty() @@ -37,20 +55,43 @@ class FunctionConstraint( false } } else { - true + false } } private fun doResolve(): Constraint { - return if (!isPrototypeFunction()) { + return if (!hasMembers()) { FunctionConstraint( owner, returnConstraints.resolve(), parameterConstraints.map { (name, constraint) -> name to constraint.resolve() } ) } else { - //TODO add function as constructor, and invocable - return classRepresentation.resolve() + if (hasNonStaticMembers()) { + classRepresentation.constructorConstraint = FunctionConstraint( + owner, + returnConstraints.resolve(), + parameterConstraints.map { (name, constraint) -> name to constraint.resolve() } + ) + + classRepresentation.resolve() + } else { + val objectRepresentation = ObjectConstraint(owner) + + val propertyNames = classRepresentation.propertyNames.filter { it != "prototype" } + + propertyNames.forEach { + objectRepresentation[it] = classRepresentation[it]!! + } + + objectRepresentation.callSignatureConstraint = FunctionConstraint( + owner, + returnConstraints.resolve(), + parameterConstraints.map { (name, constraint) -> name to constraint.resolve() } + ) + + objectRepresentation.resolve() + } } } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt index 7fb83c15c..695ba4f93 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt @@ -13,6 +13,8 @@ class ObjectConstraint( private val properties = LinkedHashMap() + var callSignatureConstraint: Constraint? = null + override fun set(name: String, data: Constraint) { properties[name] = data } @@ -49,6 +51,11 @@ class ObjectConstraint( } } + val callSignatureConstraint = callSignatureConstraint + if (callSignatureConstraint != null) { + resolvedConstraint.callSignatureConstraint = callSignatureConstraint.resolve() + } + propertyNames.forEach { resolvedConstraint[it] = this[it]!!.resolve() } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index 276b0ccf6..3c1b98cf8 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -19,7 +19,9 @@ import org.jetbrains.dukat.js.type.type.numberType import org.jetbrains.dukat.js.type.type.stringType import org.jetbrains.dukat.js.type.type.voidType import org.jetbrains.dukat.panic.raiseConcern +import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration import org.jetbrains.dukat.tsmodel.ClassDeclaration +import org.jetbrains.dukat.tsmodel.ConstructorDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.MemberDeclaration import org.jetbrains.dukat.tsmodel.ModifierDeclaration @@ -70,6 +72,19 @@ fun FunctionConstraint.toDeclaration(name: String) = FunctionDeclaration( uid = getUID() ) +fun FunctionConstraint.toConstructor() = ConstructorDeclaration( + parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, + typeParameters = emptyList(), + modifiers = EXPORT_MODIFIERS, + body = null +) + +fun FunctionConstraint.toCallSignature() = CallSignatureDeclaration( + parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, + type = returnConstraints.toType(), + typeParameters = emptyList() +) + fun FunctionDeclaration.withStaticModifier(isStatic: Boolean) : FunctionDeclaration { return this.copy(modifiers = if (isStatic) STATIC_MODIFIERS else emptyList()) } @@ -88,6 +103,11 @@ fun Constraint.toMemberDeclaration(name: String, isStatic: Boolean = false) : Me fun ClassConstraint.toDeclaration(name: String) : ClassDeclaration { val members = mutableListOf() + val constructorConstraint = constructorConstraint + if (constructorConstraint is FunctionConstraint) { + members.add(constructorConstraint.toConstructor()) + } + val prototype = this["prototype"] if (prototype is ObjectConstraint) { @@ -137,6 +157,11 @@ fun UnionTypeConstraint.toType() : UnionTypeDeclaration { fun ObjectConstraint.mapMembers() : List { val members = mutableListOf() + val callSignatureConstraint = callSignatureConstraint + if (callSignatureConstraint is FunctionConstraint) { + members.add(callSignatureConstraint.toCallSignature()) + } + members.addAll( propertyNames.mapNotNull { memberName -> this[memberName]?.toMemberDeclaration(name = memberName) @@ -146,8 +171,9 @@ fun ObjectConstraint.mapMembers() : List { if (instantiatedClass is PropertyOwner) { val classPrototype = instantiatedClass["prototype"] - if (classPrototype is ObjectConstraint) + if (classPrototype is ObjectConstraint) { members.addAll(classPrototype.mapMembers()) + } } return members From 1f5560f92610203152108356f7957d0271dcea6a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 25 Nov 2019 10:26:40 +0100 Subject: [PATCH 101/172] Add tests for functions with properties and prototype functions --- .../data/javascript/function/prototype.d.kt | 24 +++++++++++++++++++ .../data/javascript/function/prototype.d.ts | 6 +++++ .../javascript/function/withProperty.d.kt | 22 +++++++++++++++++ .../javascript/function/withProperty.d.ts | 5 ++++ 4 files changed, 57 insertions(+) create mode 100644 compiler/test/data/javascript/function/prototype.d.kt create mode 100644 compiler/test/data/javascript/function/prototype.d.ts create mode 100644 compiler/test/data/javascript/function/withProperty.d.kt create mode 100644 compiler/test/data/javascript/function/withProperty.d.ts diff --git a/compiler/test/data/javascript/function/prototype.d.kt b/compiler/test/data/javascript/function/prototype.d.kt new file mode 100644 index 000000000..4fa313a1c --- /dev/null +++ b/compiler/test/data/javascript/function/prototype.d.kt @@ -0,0 +1,24 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external open class X { + open var numProperty: Number + + companion object { + var staticNumProperty: Number + } +} \ No newline at end of file diff --git a/compiler/test/data/javascript/function/prototype.d.ts b/compiler/test/data/javascript/function/prototype.d.ts new file mode 100644 index 000000000..21fa41715 --- /dev/null +++ b/compiler/test/data/javascript/function/prototype.d.ts @@ -0,0 +1,6 @@ +function X() {} + +X.prototype.numProperty = 3 +X.staticNumProperty = 3 + +module.exports.X = X \ No newline at end of file diff --git a/compiler/test/data/javascript/function/withProperty.d.kt b/compiler/test/data/javascript/function/withProperty.d.kt new file mode 100644 index 000000000..98c9d634a --- /dev/null +++ b/compiler/test/data/javascript/function/withProperty.d.kt @@ -0,0 +1,22 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external object X { + @nativeInvoke + operator fun invoke() + var numProperty: Number +} \ No newline at end of file diff --git a/compiler/test/data/javascript/function/withProperty.d.ts b/compiler/test/data/javascript/function/withProperty.d.ts new file mode 100644 index 000000000..0481dc84f --- /dev/null +++ b/compiler/test/data/javascript/function/withProperty.d.ts @@ -0,0 +1,5 @@ +function X() {} + +X.numProperty = 3 + +module.exports.X = X \ No newline at end of file From 282c890bfebe080cfeeca091798f71bb64d5889e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 25 Nov 2019 11:46:44 +0100 Subject: [PATCH 102/172] Add array literal expressions --- .../ts-converter/src/ast/AstExpressionConverter.ts | 10 ++++++++++ .../ts-converter/src/ast/AstExpressionFactory.ts | 9 +++++++++ typescript/ts-model-proto/src/Declarations.proto | 7 ++++++- .../literal/ArrayLiteralExpressionDeclaration.kt | 7 +++++++ .../jetbrains/dukat/tsmodel/factory/convertProtobuf.kt | 4 ++++ 5 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/ArrayLiteralExpressionDeclaration.kt diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index 1b3aa636f..952846f5a 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -77,6 +77,10 @@ export class AstExpressionConverter { return AstExpressionFactory.createObjectLiteralDeclarationAsExpression(members); } + createArrayLiteralExpression(elements: Array): Expression { + return AstExpressionFactory.createArrayLiteralDeclarationAsExpression(elements); + } + createRegExLiteralExpression(value: string): Expression { return AstExpressionFactory.createRegExLiteralDeclarationAsExpression(value); } @@ -266,6 +270,10 @@ export class AstExpressionConverter { return this.createObjectLiteralExpression(members) } + convertArrayLiteralExpression(literal: ts.ArrayLiteralExpression): Expression { + return this.createArrayLiteralExpression(literal.elements.map((element) => this.convertExpression(element))) + } + convertRegExLiteralExpression(literal: ts.RegularExpressionLiteral): Expression { return this.createRegExLiteralExpression(literal.getText()) } @@ -328,6 +336,8 @@ export class AstExpressionConverter { return this.convertLiteralExpression(expression); } else if (ts.isObjectLiteralExpression(expression)) { return this.convertObjectLiteralExpression(expression); + } else if (ts.isArrayLiteralExpression(expression)) { + return this.convertArrayLiteralExpression(expression); } else if (ts.isToken(expression)) { return this.convertToken(expression) } else { diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index a5c5eab99..19502b692 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -183,6 +183,15 @@ export class AstExpressionFactory { return this.asExpression(literalExpression); } + static createArrayLiteralDeclarationAsExpression(elements: Array): Expression { + let arrayLiteral = new declarations.ArrayLiteralExpressionDeclarationProto(); + arrayLiteral.setElementsList(elements); + + let literalExpression = new declarations.LiteralExpressionDeclarationProto(); + literalExpression.setArrayliteral(arrayLiteral); + return this.asExpression(literalExpression); + } + static createRegExLiteralDeclarationAsExpression(value: string): Expression { let regExLiteralExpression = new declarations.RegExLiteralExpressionDeclarationProto(); regExLiteralExpression.setValue(value); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index ac4282b68..643d5f1a3 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -182,6 +182,10 @@ message ObjectLiteralExpressionDeclarationProto { repeated MemberDeclarationProto members = 1; } +message ArrayLiteralExpressionDeclarationProto { + repeated ExpressionDeclarationProto elements = 1; +} + message RegExLiteralExpressionDeclarationProto { string value = 1; } @@ -193,7 +197,8 @@ message LiteralExpressionDeclarationProto { NumericLiteralExpressionDeclarationProto numericLiteral = 3; BigIntLiteralExpressionDeclarationProto bigIntLiteral = 4; ObjectLiteralExpressionDeclarationProto objectLiteral = 5; - RegExLiteralExpressionDeclarationProto regExLiteral = 6; + ArrayLiteralExpressionDeclarationProto arrayLiteral = 6; + RegExLiteralExpressionDeclarationProto regExLiteral = 7; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/ArrayLiteralExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/ArrayLiteralExpressionDeclaration.kt new file mode 100644 index 000000000..da3887232 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/literal/ArrayLiteralExpressionDeclaration.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.tsmodel.expression.literal + +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +data class ArrayLiteralExpressionDeclaration( + val elements: List +) : LiteralExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 411f7bf44..f7e39e6eb 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -45,6 +45,7 @@ import org.jetbrains.dukat.tsmodel.expression.TypeOfExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.UnknownExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.literal.ArrayLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BigIntLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.BooleanLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.literal.LiteralExpressionDeclaration @@ -64,6 +65,7 @@ import org.jetbrains.dukat.tsmodel.types.TupleDeclaration import org.jetbrains.dukat.tsmodel.types.TypeDeclaration import org.jetbrains.dukat.tsmodel.types.TypeParamReferenceDeclaration import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration +import org.jetbrains.dukat.tsmodelproto.ArrayLiteralExpressionDeclarationProto import org.jetbrains.dukat.tsmodelproto.BigIntLiteralExpressionDeclarationProto import org.jetbrains.dukat.tsmodelproto.BinaryExpressionDeclarationProto import org.jetbrains.dukat.tsmodelproto.BlockDeclarationProto @@ -476,6 +478,7 @@ fun StringLiteralExpressionDeclarationProto.convert() = StringLiteralExpressionD fun BooleanLiteralExpressionDeclarationProto.convert() = BooleanLiteralExpressionDeclaration(value) fun RegExLiteralExpressionDeclarationProto.convert() = RegExLiteralExpressionDeclaration(value) fun ObjectLiteralExpressionDeclarationProto.convert() = ObjectLiteralExpressionDeclaration(membersList.map { it.convert() }) +fun ArrayLiteralExpressionDeclarationProto.convert() = ArrayLiteralExpressionDeclaration(elementsList.map { it.convert() }) fun LiteralExpressionDeclarationProto.convert() : LiteralExpressionDeclaration { return when { @@ -484,6 +487,7 @@ fun LiteralExpressionDeclarationProto.convert() : LiteralExpressionDeclaration { hasStringLiteral() -> stringLiteral.convert() hasBooleanLiteral() -> booleanLiteral.convert() hasObjectLiteral() -> objectLiteral.convert() + hasArrayLiteral() -> arrayLiteral.convert() hasRegExLiteral() -> regExLiteral.convert() else -> throw Exception("unknown literalExpression: ${this}") } From 3355871e29e2de98c37d7c0ea22d245a5767ff6f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 2 Dec 2019 12:46:36 +0100 Subject: [PATCH 103/172] Add conditional expression --- .../ts-converter/src/ast/AstExpressionConverter.ts | 14 ++++++++++++++ .../ts-converter/src/ast/AstExpressionFactory.ts | 12 ++++++++++++ typescript/ts-model-proto/src/Declarations.proto | 9 ++++++++- .../expression/ConditionalExpressionDeclaration.kt | 9 +++++++++ .../dukat/tsmodel/factory/convertProtobuf.kt | 11 +++++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/ConditionalExpressionDeclaration.kt diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index 952846f5a..4d39a3a95 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -53,6 +53,10 @@ export class AstExpressionConverter { return AstExpressionFactory.createNewExpressionDeclarationAsExpression(expression, args); } + createConditionalExpression(condition: Expression, whenTrue: Expression, whenFalse: Expression) { + return AstExpressionFactory.createConditionalExpressionDeclarationAsExpression(condition, whenTrue, whenFalse); + } + createNameExpression(name: NameEntity): Expression { return AstExpressionFactory.createNameExpressionDeclarationAsExpression(name) } @@ -180,6 +184,14 @@ export class AstExpressionConverter { ) } + convertConditionalExpression(expression: ts.ConditionalExpression): Expression { + return this.createConditionalExpression( + this.convertExpression(expression.condition), + this.convertExpression(expression.whenTrue), + this.convertExpression(expression.whenFalse) + ) + } + convertNameExpression(name: ts.EntityName): Expression { return this.createNameExpression( this.convertEntityName(name) @@ -338,6 +350,8 @@ export class AstExpressionConverter { return this.convertObjectLiteralExpression(expression); } else if (ts.isArrayLiteralExpression(expression)) { return this.convertArrayLiteralExpression(expression); + } else if (ts.isConditionalExpression(expression)) { + return this.convertConditionalExpression(expression); } else if (ts.isToken(expression)) { return this.convertToken(expression) } else { diff --git a/typescript/ts-converter/src/ast/AstExpressionFactory.ts b/typescript/ts-converter/src/ast/AstExpressionFactory.ts index 19502b692..896cd2a3d 100644 --- a/typescript/ts-converter/src/ast/AstExpressionFactory.ts +++ b/typescript/ts-converter/src/ast/AstExpressionFactory.ts @@ -80,6 +80,18 @@ export class AstExpressionFactory { return expressionProto; } + static createConditionalExpressionDeclarationAsExpression(condition: Expression, whenTrue: Expression, whenFalse: Expression) { + let conditionalExpression = new declarations.ConditionalExpressionDeclarationProto(); + + conditionalExpression.setCondition(condition); + conditionalExpression.setWhentrue(whenTrue); + conditionalExpression.setWhenfalse(whenFalse); + + let expressionProto = new declarations.ExpressionDeclarationProto(); + expressionProto.setConditionalexpression(conditionalExpression); + return expressionProto; + } + static createQualifierAsNameEntity(left: NameEntity, right: IdentifierDeclaration): NameEntity { let qualifier = new declarations.QualifierDeclarationProto(); qualifier.setLeft(left); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index 643d5f1a3..8bd1bb4af 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -242,6 +242,12 @@ message NewExpressionDeclarationProto { repeated ExpressionDeclarationProto arguments = 2; } +message ConditionalExpressionDeclarationProto { + ExpressionDeclarationProto condition = 1; + ExpressionDeclarationProto whenTrue = 2; + ExpressionDeclarationProto whenFalse = 3; +} + message UnknownExpressionDeclarationProto { string meta = 1; } @@ -259,7 +265,8 @@ message ExpressionDeclarationProto { PropertyAccessExpressionDeclarationProto propertyAccessExpression = 9; ElementAccessExpressionDeclarationProto elementAccessExpression = 10; NewExpressionDeclarationProto newExpression = 11; - UnknownExpressionDeclarationProto unknownExpression = 12; + ConditionalExpressionDeclarationProto conditionalExpression = 12; + UnknownExpressionDeclarationProto unknownExpression = 13; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/ConditionalExpressionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/ConditionalExpressionDeclaration.kt new file mode 100644 index 000000000..00f86bc69 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/expression/ConditionalExpressionDeclaration.kt @@ -0,0 +1,9 @@ +package org.jetbrains.dukat.tsmodel.expression + +import org.jetbrains.dukat.tsmodel.ExpressionDeclaration + +data class ConditionalExpressionDeclaration( + val condition: ExpressionDeclaration, + val whenTrue: ExpressionDeclaration, + val whenFalse: ExpressionDeclaration +) : ExpressionDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index f7e39e6eb..d11af003f 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -38,6 +38,7 @@ import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.WhileStatementDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.CallExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.ConditionalExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.ElementAccessExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.NewExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaration @@ -73,6 +74,7 @@ import org.jetbrains.dukat.tsmodelproto.BooleanLiteralExpressionDeclarationProto import org.jetbrains.dukat.tsmodelproto.CallExpressionDeclarationProto import org.jetbrains.dukat.tsmodelproto.CallSignatureDeclarationProto import org.jetbrains.dukat.tsmodelproto.ClassDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ConditionalExpressionDeclarationProto import org.jetbrains.dukat.tsmodelproto.ConstructorDeclarationProto import org.jetbrains.dukat.tsmodelproto.DefinitionInfoDeclarationProto import org.jetbrains.dukat.tsmodelproto.ElementAccessExpressionDeclarationProto @@ -514,6 +516,14 @@ fun NewExpressionDeclarationProto.convert(): NewExpressionDeclaration { ) } +fun ConditionalExpressionDeclarationProto.convert(): ConditionalExpressionDeclaration { + return ConditionalExpressionDeclaration( + condition = condition.convert(), + whenTrue = whenTrue.convert(), + whenFalse = whenFalse.convert() + ) +} + fun UnknownExpressionDeclarationProto.convert() : UnknownExpressionDeclaration { return UnknownExpressionDeclaration( meta = meta @@ -533,6 +543,7 @@ fun ExpressionDeclarationProto.convert() : ExpressionDeclaration { hasPropertyAccessExpression() -> propertyAccessExpression.convert() hasElementAccessExpression() -> elementAccessExpression.convert() hasNewExpression() -> newExpression.convert() + hasConditionalExpression() -> conditionalExpression.convert() hasUnknownExpression() -> unknownExpression.convert() else -> throw Exception("unknown expression: ${this}") } From 541612b78d73237139d7d9096ec08e3278b193ee Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 2 Dec 2019 13:17:46 +0100 Subject: [PATCH 104/172] Support conditional expression --- .../jetbrains/dukat/js/type/analysis/expression.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 1944cdd10..0b166dfb5 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -29,6 +29,7 @@ import org.jetbrains.dukat.tsmodel.ModifierDeclaration import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.CallExpressionDeclaration +import org.jetbrains.dukat.tsmodel.expression.ConditionalExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.NewExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.PropertyAccessExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.TypeOfExpressionDeclaration @@ -232,6 +233,15 @@ fun NewExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: Pa ) } +fun ConditionalExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { + condition.calculateConstraints(owner, path) += BooleanTypeConstraint + + return when (path.getNextDirection()) { + PathWalker.Direction.First -> whenTrue.calculateConstraints(owner, path) + PathWalker.Direction.Second -> whenFalse.calculateConstraints(owner, path) + } +} + fun ObjectLiteralExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : ObjectConstraint { val obj = ObjectConstraint(owner) members.forEach { it.addTo(obj, path) } @@ -260,6 +270,7 @@ fun ExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathW is TypeOfExpressionDeclaration -> this.calculateConstraints(owner, path) is CallExpressionDeclaration -> this.calculateConstraints(owner, path) is NewExpressionDeclaration -> this.calculateConstraints(owner, path) + is ConditionalExpressionDeclaration -> this.calculateConstraints(owner, path) is LiteralExpressionDeclaration -> this.calculateConstraints(owner, path) else -> CompositeConstraint(NoTypeConstraint) } From 16e969c8946b20b544d0e589d6f0ff73722a3835 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 2 Dec 2019 13:21:56 +0100 Subject: [PATCH 105/172] Fix test --- compiler/test/data/javascript/misc/random.d.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/test/data/javascript/misc/random.d.kt b/compiler/test/data/javascript/misc/random.d.kt index b1eee3c21..f703d2c72 100644 --- a/compiler/test/data/javascript/misc/random.d.kt +++ b/compiler/test/data/javascript/misc/random.d.kt @@ -27,6 +27,6 @@ external object _ { external fun keyInObj(value: Any?, key: Any?, obj: Any?): Boolean -external fun createPredicateIndexFinder(array: Any?, predicate: Any?, context: Any?, dir: Any?): Number +external fun createPredicateIndexFinder(array: Any?, predicate: Any?, context: Any?, dir: Number): Number external fun isArrayLike(collection: Any?): Boolean \ No newline at end of file From 0d11075cf2ee87e4730b7b9cb1009a26f5e0dc73 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Dec 2019 10:45:06 +0100 Subject: [PATCH 106/172] Restrict types for arguments, based on properties accessed of type. --- .../dukat/js/type/analysis/expression.kt | 13 +++-- .../composite/CompositeConstraint.kt | 56 +++++++++++++++---- .../reference/ReferenceConstraint.kt | 4 +- .../reference/call/CallArgumentConstraint.kt | 6 +- 4 files changed, 57 insertions(+), 22 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 0b166dfb5..6b8797380 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -78,7 +78,7 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) : FunctionConstraint? { val parameterConstraints = MutableList(parameters.size) { i -> // Store constraints of parameters in scope, // and in parameter list (in case the variable is replaced) - val parameterConstraint = CompositeConstraint() + val parameterConstraint = CompositeConstraint(owner) functionScope[parameters[i].name] = parameterConstraint parameters[i].name to parameterConstraint } @@ -172,7 +172,7 @@ fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: else -> { left.calculateConstraints(owner, path) right.calculateConstraints(owner, path) - CompositeConstraint(NoTypeConstraint) + CompositeConstraint(owner, NoTypeConstraint) } } } @@ -194,7 +194,7 @@ fun UnaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: BooleanTypeConstraint } else -> { - CompositeConstraint(NoTypeConstraint) + CompositeConstraint(owner, NoTypeConstraint) } } } @@ -210,6 +210,7 @@ fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: P argumentConstraints.forEachIndexed { argumentNumber, arg -> arg += CallArgumentConstraint( + owner, callTargetConstraints, argumentNumber ) @@ -255,7 +256,7 @@ fun LiteralExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path is BigIntLiteralExpressionDeclaration -> BigIntTypeConstraint is BooleanLiteralExpressionDeclaration -> BooleanTypeConstraint is ObjectLiteralExpressionDeclaration -> this.calculateConstraints(owner, path) - else -> raiseConcern("Unexpected literal expression type <${this::class}>") { CompositeConstraint(NoTypeConstraint) } + else -> raiseConcern("Unexpected literal expression type <${this::class}>") { CompositeConstraint(owner, NoTypeConstraint) } } } @@ -264,7 +265,7 @@ fun ExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathW is FunctionDeclaration -> this.addTo(owner) ?: NoTypeConstraint is ClassDeclaration -> this.addTo(owner, path) ?: NoTypeConstraint is IdentifierExpressionDeclaration -> owner[this] ?: ReferenceConstraint(this.identifier, owner) - is PropertyAccessExpressionDeclaration -> owner[this, path] ?: CompositeConstraint() //TODO replace this with a reference constraint (of some sort) + is PropertyAccessExpressionDeclaration -> owner[this, path] ?: CompositeConstraint(owner) //TODO replace this with a reference constraint (of some sort) is BinaryExpressionDeclaration -> this.calculateConstraints(owner, path) is UnaryExpressionDeclaration -> this.calculateConstraints(owner, path) is TypeOfExpressionDeclaration -> this.calculateConstraints(owner, path) @@ -272,6 +273,6 @@ fun ExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathW is NewExpressionDeclaration -> this.calculateConstraints(owner, path) is ConditionalExpressionDeclaration -> this.calculateConstraints(owner, path) is LiteralExpressionDeclaration -> this.calculateConstraints(owner, path) - else -> CompositeConstraint(NoTypeConstraint) + else -> CompositeConstraint(owner, NoTypeConstraint) } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt index 60ee30b6d..1c41b81b2 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt @@ -7,10 +7,34 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstrain import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint +import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -class CompositeConstraint(private val constraints: MutableSet) : Constraint { - constructor(vararg constraints: Constraint) : this(mutableSetOf(*constraints)) - constructor(constraints: List) : this(constraints.toMutableSet()) +class CompositeConstraint( + override val owner: PropertyOwner, + private val constraints: MutableSet +) : PropertyOwner, Constraint { + constructor(owner: PropertyOwner, vararg constraints: Constraint) : this(owner, mutableSetOf(*constraints)) + constructor(owner: PropertyOwner, constraints: List) : this(owner, constraints.toMutableSet()) + + private val properties = LinkedHashMap() + + override fun set(name: String, data: Constraint) { + properties[name] = data + } + + override fun get(name: String): Constraint? { + val constraint = properties[name] + + return if (constraint != null) { + constraint + } else { + val newConstraint = CompositeConstraint(owner) + this[name] = newConstraint + newConstraint + } + } override operator fun plusAssign(other: Constraint) { constraints += other @@ -31,15 +55,23 @@ class CompositeConstraint(private val constraints: MutableSet) : Con } override fun resolve(): Constraint { - val resolvedConstraints = getFlatConstraints().map { it.resolve() } - - return when { - resolvedConstraints.contains(NumberTypeConstraint) -> NumberTypeConstraint - resolvedConstraints.contains(BigIntTypeConstraint) -> BigIntTypeConstraint - resolvedConstraints.contains(BooleanTypeConstraint) -> BooleanTypeConstraint - resolvedConstraints.contains(StringTypeConstraint) -> StringTypeConstraint - resolvedConstraints.contains(RecursiveConstraint) -> RecursiveConstraint - else -> NoTypeConstraint + return if (properties.isNotEmpty()) { + ObjectConstraint(owner).apply { + properties.forEach { (name, value) -> + this[name] = value.resolve() + } + } + } else { + val resolvedConstraints = getFlatConstraints().map { it.resolve() } + + when { + resolvedConstraints.contains(NumberTypeConstraint) -> NumberTypeConstraint + resolvedConstraints.contains(BigIntTypeConstraint) -> BigIntTypeConstraint + resolvedConstraints.contains(BooleanTypeConstraint) -> BooleanTypeConstraint + resolvedConstraints.contains(StringTypeConstraint) -> StringTypeConstraint + resolvedConstraints.contains(RecursiveConstraint) -> RecursiveConstraint + else -> NoTypeConstraint + } } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt index 7e9070422..e685b4c70 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt @@ -47,13 +47,13 @@ open class ReferenceConstraint( override fun resolve(): Constraint { return when (resolutionState) { ResolutionState.UNRESOLVED -> { - resolvedConstraint = resolveInOwner(owner) ?: CompositeConstraint() + resolvedConstraint = resolveInOwner(owner) ?: CompositeConstraint(owner) resolutionState = ResolutionState.RESOLVED return resolvedConstraint!! } ResolutionState.RESOLVING -> { - raiseConcern("Invalid converter state!") { CompositeConstraint() } + raiseConcern("Invalid converter state!") { CompositeConstraint(owner) } } ResolutionState.RESOLVED -> { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt index c3bba948f..8ef1a8f6c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt @@ -4,8 +4,10 @@ import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint +import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class CallArgumentConstraint( + private val owner: PropertyOwner, private val callTarget: Constraint, private val argumentNum: Int ) : ImmutableConstraint { @@ -16,10 +18,10 @@ class CallArgumentConstraint( if (functionConstraint.parameterConstraints.size > argumentNum) { functionConstraint.parameterConstraints[argumentNum].second } else { - CompositeConstraint() + CompositeConstraint(owner) } } else { - CallArgumentConstraint(functionConstraint, argumentNum) + CallArgumentConstraint(owner, functionConstraint, argumentNum) } } } \ No newline at end of file From 58d2705b46acc0cf0912a2c7cc5bb9d80910872f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Dec 2019 11:21:49 +0100 Subject: [PATCH 107/172] Differentiate type passed into a function, and type after modification in function --- .../data/javascript/arguments/modified.d.kt | 27 +++++++++++ .../data/javascript/arguments/modified.d.ts | 8 ++++ .../dukat/js/type/constraint/Constraint.kt | 19 ++++++++ .../composite/CompositeConstraint.kt | 45 +++++++++++-------- .../immutable/ImmutableConstraint.kt | 2 + .../properties/FunctionConstraint.kt | 6 +-- 6 files changed, 86 insertions(+), 21 deletions(-) create mode 100644 compiler/test/data/javascript/arguments/modified.d.kt create mode 100644 compiler/test/data/javascript/arguments/modified.d.ts diff --git a/compiler/test/data/javascript/arguments/modified.d.kt b/compiler/test/data/javascript/arguments/modified.d.kt new file mode 100644 index 000000000..0373c7c82 --- /dev/null +++ b/compiler/test/data/javascript/arguments/modified.d.kt @@ -0,0 +1,27 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface `T$0` { + var value: Number +} + +external interface `T$1` { + var value: Number + var negative: Number +} + +external fun addNegativeValue(o: `T$0`): `T$1` \ No newline at end of file diff --git a/compiler/test/data/javascript/arguments/modified.d.ts b/compiler/test/data/javascript/arguments/modified.d.ts new file mode 100644 index 000000000..36042c0c6 --- /dev/null +++ b/compiler/test/data/javascript/arguments/modified.d.ts @@ -0,0 +1,8 @@ + +function addNegativeValue(o) { + o.negative = -o.value + + return o +} + +exports.addNegativeValue = addNegativeValue diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt index a676ea724..0dc7ffee0 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt @@ -9,5 +9,24 @@ interface Constraint { } } + /** + * Same as [resolve], but called instead, + * when resolving a constraint to get a type + * that can be used in a manner this constraint can. + * + * (For example, when passing an object to a + * function, and adding an "x" property to it, + * this resolution will not contain it, but + * [resolve] will) + */ + fun resolveAsInput() : Constraint + + /** + * Resolves all references and other constraints it contains, + * to turn this constraint into one that represents a type. + * + * Should only be run after collecting all constraints, + * and constraint should not be modified afterwards. + */ fun resolve() : Constraint } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt index 1c41b81b2..8ee9c6455 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt @@ -8,7 +8,6 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConst import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint -import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class CompositeConstraint( @@ -18,20 +17,22 @@ class CompositeConstraint( constructor(owner: PropertyOwner, vararg constraints: Constraint) : this(owner, mutableSetOf(*constraints)) constructor(owner: PropertyOwner, constraints: List) : this(owner, constraints.toMutableSet()) - private val properties = LinkedHashMap() + private val neededProperties = LinkedHashMap() + private val allProperties = LinkedHashMap() override fun set(name: String, data: Constraint) { - properties[name] = data + allProperties[name] = data } - override fun get(name: String): Constraint? { - val constraint = properties[name] + override fun get(name: String) : Constraint? { + val constraint = allProperties[name] return if (constraint != null) { constraint } else { val newConstraint = CompositeConstraint(owner) - this[name] = newConstraint + neededProperties[name] = newConstraint + allProperties[name] = newConstraint newConstraint } } @@ -44,7 +45,7 @@ class CompositeConstraint( constraints.addAll(others) } - fun getFlatConstraints() : List { + private fun getFlatConstraints() : List { return constraints.flatMap { constraint -> if(constraint is CompositeConstraint) { constraint.getFlatConstraints() @@ -54,7 +55,20 @@ class CompositeConstraint( } } - override fun resolve(): Constraint { + private fun resolveToBasicType() : Constraint { + val resolvedConstraints = getFlatConstraints().map { it.resolve() } + + return when { + resolvedConstraints.contains(NumberTypeConstraint) -> NumberTypeConstraint + resolvedConstraints.contains(BigIntTypeConstraint) -> BigIntTypeConstraint + resolvedConstraints.contains(BooleanTypeConstraint) -> BooleanTypeConstraint + resolvedConstraints.contains(StringTypeConstraint) -> StringTypeConstraint + resolvedConstraints.contains(RecursiveConstraint) -> RecursiveConstraint + else -> NoTypeConstraint + } + } + + private fun resolveWithProperties(properties: Map) : Constraint { return if (properties.isNotEmpty()) { ObjectConstraint(owner).apply { properties.forEach { (name, value) -> @@ -62,16 +76,11 @@ class CompositeConstraint( } } } else { - val resolvedConstraints = getFlatConstraints().map { it.resolve() } - - when { - resolvedConstraints.contains(NumberTypeConstraint) -> NumberTypeConstraint - resolvedConstraints.contains(BigIntTypeConstraint) -> BigIntTypeConstraint - resolvedConstraints.contains(BooleanTypeConstraint) -> BooleanTypeConstraint - resolvedConstraints.contains(StringTypeConstraint) -> StringTypeConstraint - resolvedConstraints.contains(RecursiveConstraint) -> RecursiveConstraint - else -> NoTypeConstraint - } + resolveToBasicType() } } + + override fun resolve() = resolveWithProperties(allProperties) + + override fun resolveAsInput() = resolveWithProperties(neededProperties) } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/ImmutableConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/ImmutableConstraint.kt index 7be85bfcf..02fa5bd75 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/ImmutableConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/ImmutableConstraint.kt @@ -4,4 +4,6 @@ import org.jetbrains.dukat.js.type.constraint.Constraint interface ImmutableConstraint : Constraint { override operator fun plusAssign(other: Constraint) { /* do nothing */ } + + override fun resolveAsInput() = resolve() } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt index 83ceb0832..a17dad3e8 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt @@ -64,14 +64,14 @@ class FunctionConstraint( FunctionConstraint( owner, returnConstraints.resolve(), - parameterConstraints.map { (name, constraint) -> name to constraint.resolve() } + parameterConstraints.map { (name, constraint) -> name to constraint.resolveAsInput() } ) } else { if (hasNonStaticMembers()) { classRepresentation.constructorConstraint = FunctionConstraint( owner, returnConstraints.resolve(), - parameterConstraints.map { (name, constraint) -> name to constraint.resolve() } + parameterConstraints.map { (name, constraint) -> name to constraint.resolveAsInput() } ) classRepresentation.resolve() @@ -87,7 +87,7 @@ class FunctionConstraint( objectRepresentation.callSignatureConstraint = FunctionConstraint( owner, returnConstraints.resolve(), - parameterConstraints.map { (name, constraint) -> name to constraint.resolve() } + parameterConstraints.map { (name, constraint) -> name to constraint.resolveAsInput() } ) objectRepresentation.resolve() From 48efc9db3128de82f42fb96e35e46877f5649580 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Dec 2019 11:33:19 +0100 Subject: [PATCH 108/172] Delete unneeded test --- .../test/data/javascript/misc/random.d.kt | 32 ------- .../test/data/javascript/misc/random.d.ts | 89 ------------------- 2 files changed, 121 deletions(-) delete mode 100644 compiler/test/data/javascript/misc/random.d.kt delete mode 100644 compiler/test/data/javascript/misc/random.d.ts diff --git a/compiler/test/data/javascript/misc/random.d.kt b/compiler/test/data/javascript/misc/random.d.kt deleted file mode 100644 index f703d2c72..000000000 --- a/compiler/test/data/javascript/misc/random.d.kt +++ /dev/null @@ -1,32 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") - -import kotlin.js.* -import kotlin.js.Json -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external object _ { - fun values(obj: Any?): Any? - fun keys(obj: Any?): Any? - fun negate(predicate: Any?): Boolean - fun isArray(obj: Any?): Boolean - fun isObject(obj: Any?): Boolean - fun isElement(obj: Any?): Boolean - fun isEmpty(obj: Any?): Boolean -} - -external fun keyInObj(value: Any?, key: Any?, obj: Any?): Boolean - -external fun createPredicateIndexFinder(array: Any?, predicate: Any?, context: Any?, dir: Number): Number - -external fun isArrayLike(collection: Any?): Boolean \ No newline at end of file diff --git a/compiler/test/data/javascript/misc/random.d.ts b/compiler/test/data/javascript/misc/random.d.ts deleted file mode 100644 index 31fa60fba..000000000 --- a/compiler/test/data/javascript/misc/random.d.ts +++ /dev/null @@ -1,89 +0,0 @@ -let _ = {} - -// ??? -// Retrieve the values of an object's properties. -// Array -function values(obj) { - var keys = _.keys(obj); - var length = keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[keys[i]]; - } - return values; -} -_.values = values - -// Retrieve the names of an object's own properties. -// Delegates to **ECMAScript 5**'s native Object.keys. -function keys(obj) { - if (!_.isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (has(obj, key)) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; -} -_.keys = keys - -function negate(predicate) { - return !predicate.apply(this, arguments); -} -_.negate = negate - -// Is a given value an array? -// Delegates to ECMA5's native Array.isArray -function isArray(obj) { - return toString.call(obj) === '[object Array]'; -} -_.isArray = isArray - -// Is a given variable an object? -function isObject(obj) { - var type = typeof obj; - return type === 'function' || type === 'object' && !!obj; -} -_.isObject = isObject - -// Is a given value a DOM element? -function isElement(obj) { - return !!(obj && obj.nodeType === 1); -} -_.isElement = isElement - -// Is a given array, string, or object empty? -// An "empty" object has no enumerable own-properties. -function isEmpty(obj) { - if (obj == null) return true; - if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; - return _.keys(obj).length === 0; -} -_.isEmpty = isEmpty - -// Internal pick helper function to determine if obj has key key. -function keyInObj(value, key, obj) { - return key in obj; -} - -// Generator function to create the findIndex and findLastIndex functions. -function createPredicateIndexFinder(array, predicate, context, dir) { - predicate = cb(predicate, context); - var length = getLength(array); - var index = dir > 0 ? 0 : length - 1; - for (; index >= 0 && index < length; index += dir) { - if (predicate(array[index], index, array)) return index; - } - return -1; -} - -function isArrayLike(collection) { - var length = getLength(collection); - return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; -} - - -module.exports._ = _ -module.exports.keyInObj = keyInObj -module.exports.createPredicateIndexFinder = createPredicateIndexFinder -module.exports.isArrayLike = isArrayLike From 74bddba657b32a30d02bf97011b8f054666ecc41 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Dec 2019 11:36:28 +0100 Subject: [PATCH 109/172] Fix implied type of boolean, when using value as condition --- .../jetbrains/dukat/js/type/analysis/calculateConstraints.kt | 4 ++-- .../src/org/jetbrains/dukat/js/type/analysis/expression.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt index d18f6deec..b9e101f6f 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt @@ -27,7 +27,7 @@ fun VariableDeclaration.addTo(owner: PropertyOwner, path: PathWalker) { } fun IfStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { - condition.calculateConstraints(owner, path) += BooleanTypeConstraint + condition.calculateConstraints(owner, path) return when (path.getNextDirection()) { PathWalker.Direction.First -> thenStatement.calculateConstraints(owner, path) @@ -36,7 +36,7 @@ fun IfStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: Path } fun WhileStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { - condition.calculateConstraints(owner, path) += BooleanTypeConstraint + condition.calculateConstraints(owner, path) return when (path.getNextDirection()) { PathWalker.Direction.First -> statement.calculateConstraints(owner, path) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 6b8797380..580a315d5 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -235,7 +235,7 @@ fun NewExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: Pa } fun ConditionalExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { - condition.calculateConstraints(owner, path) += BooleanTypeConstraint + condition.calculateConstraints(owner, path) return when (path.getNextDirection()) { PathWalker.Direction.First -> whenTrue.calculateConstraints(owner, path) From 5752599c771d3ae1e342a87e438ee58d0c3c2665 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Dec 2019 11:41:27 +0100 Subject: [PATCH 110/172] Fix constraints not being resolved in certain situations --- .../dukat/js/type/export_resolution/CommonJSExportResolver.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSExportResolver.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSExportResolver.kt index e2c1de7a5..c1edd04a7 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSExportResolver.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSExportResolver.kt @@ -9,7 +9,7 @@ class CommonJSExportResolver : ExportResolver { private val generalExportResolver = GeneralExportResolver() override fun resolve(scope: Scope): List { - val moduleObject = scope["module"] + val moduleObject = scope["module"].resolve() if (moduleObject is ObjectConstraint) { val exportsObject = moduleObject["exports"] From 3fdc9472e340f4134e27033e3ab18ec6e62c62e4 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Dec 2019 16:32:02 +0100 Subject: [PATCH 111/172] Resolve properties of arguments as arguments themselves --- .../js/type/constraint/composite/CompositeConstraint.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt index 8ee9c6455..78dd00ae3 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt @@ -7,6 +7,7 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstrain import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner @@ -68,11 +69,11 @@ class CompositeConstraint( } } - private fun resolveWithProperties(properties: Map) : Constraint { + private fun resolveWithProperties(properties: Map, resolveConstraint: (Constraint) -> Constraint) : Constraint { return if (properties.isNotEmpty()) { ObjectConstraint(owner).apply { properties.forEach { (name, value) -> - this[name] = value.resolve() + this[name] = resolveConstraint(value) } } } else { @@ -80,7 +81,7 @@ class CompositeConstraint( } } - override fun resolve() = resolveWithProperties(allProperties) + override fun resolve() = resolveWithProperties(allProperties, Constraint::resolve) - override fun resolveAsInput() = resolveWithProperties(neededProperties) + override fun resolveAsInput() = resolveWithProperties(neededProperties, Constraint::resolveAsInput) } \ No newline at end of file From 389048cb5e32905dbe4be53a0370c4a4935c19f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Dec 2019 17:12:00 +0100 Subject: [PATCH 112/172] Convert arrow functions as functions without name, and single return statement, if nessecary --- .../src/ast/AstExpressionConverter.ts | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/typescript/ts-converter/src/ast/AstExpressionConverter.ts b/typescript/ts-converter/src/ast/AstExpressionConverter.ts index fa08b4c94..814cbea9d 100644 --- a/typescript/ts-converter/src/ast/AstExpressionConverter.ts +++ b/typescript/ts-converter/src/ast/AstExpressionConverter.ts @@ -118,6 +118,22 @@ export class AstExpressionConverter { ) } + convertBody(body: ts.Node | null): Block | null { + if (body) { + if (ts.isBlock(body)) { + return this.astConverter.convertBlock(body) + } else { + return this.astFactory.createBlockDeclaration( + [ + this.astFactory.createReturnStatement(this.convertExpression(body)) + ] + ) + } + } else { + return null + } + } + convertFunctionExpression(expression: ts.FunctionExpression): Expression { let name = expression.name ? expression.name.getText() : ""; @@ -135,10 +151,14 @@ export class AstExpressionConverter { returnType, typeParameterDeclarations, this.astConverter.convertModifiers(expression.modifiers), - this.astConverter.convertBlock(expression.body) + this.convertBody(expression.body) ) } + convertArrowFunctionExpression(expression: ts.ArrowFunction): Expression { + return this.convertFunctionExpression(expression) + } + convertClassExpression(expression: ts.ClassExpression): Expression { return this.createClassExpression( this.astFactory.createIdentifierDeclarationAsNameEntity(""), @@ -330,6 +350,8 @@ export class AstExpressionConverter { return this.convertPostfixUnaryExpression(expression) } else if (ts.isFunctionExpression(expression)) { return this.convertFunctionExpression(expression) + } else if (ts.isArrowFunction(expression)) { + return this.convertArrowFunctionExpression(expression) } else if (ts.isClassExpression(expression)) { return this.convertClassExpression(expression) } else if (ts.isTypeOfExpression(expression)) { From c72a7746bda3a507190abc3603825d5bf98a0e8e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Dec 2019 10:33:39 +0100 Subject: [PATCH 113/172] Add simple test for property access of function argument --- .../data/javascript/arguments/properties.d.kt | 22 +++++++++++++++++++ .../data/javascript/arguments/properties.d.ts | 6 +++++ 2 files changed, 28 insertions(+) create mode 100644 compiler/test/data/javascript/arguments/properties.d.kt create mode 100644 compiler/test/data/javascript/arguments/properties.d.ts diff --git a/compiler/test/data/javascript/arguments/properties.d.kt b/compiler/test/data/javascript/arguments/properties.d.kt new file mode 100644 index 000000000..d740c64c0 --- /dev/null +++ b/compiler/test/data/javascript/arguments/properties.d.kt @@ -0,0 +1,22 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface `T$0` { + var length: Number +} + +external fun getLength(x: `T$0`): Number \ No newline at end of file diff --git a/compiler/test/data/javascript/arguments/properties.d.ts b/compiler/test/data/javascript/arguments/properties.d.ts new file mode 100644 index 000000000..13ac416b3 --- /dev/null +++ b/compiler/test/data/javascript/arguments/properties.d.ts @@ -0,0 +1,6 @@ + +function getLength(x) { + return --x.length +} + +exports.getLength = getLength From 3bf5ad332efbe710eac6536b99bf5b5ad266fe7c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Dec 2019 11:16:37 +0100 Subject: [PATCH 114/172] Remove outdated TODOs --- .../constraint/reference/PropertyOwnerReferenceConstraint.kt | 1 - .../js/type/constraint/resolution/constraintToDeclaration.kt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt index 6b8a1606c..69ebd9253 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt @@ -24,7 +24,6 @@ abstract class PropertyOwnerReferenceConstraint(parent: PropertyOwner) : Propert protected fun Constraint.resolveWithProperties() : Constraint { if(this is PropertyOwner) { modifiedProperties.forEach { (name, constraint) -> - //TODO take composite constraints into account here this[name] = constraint } } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index 78bd62b44..73adf0b0b 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -135,7 +135,7 @@ fun ClassConstraint.toDeclaration(name: String) : ClassDeclaration { name = IdentifierEntity(name), members = members, typeParameters = emptyList(), - parentEntities = emptyList(), //TODO support inheritance, + parentEntities = emptyList(), modifiers = EXPORT_MODIFIERS, uid = getUID() ) From 2410b6dbd1d8e6a7abed902dc4c7babeb98f19d1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Dec 2019 11:22:42 +0100 Subject: [PATCH 115/172] Remove outdated TODOs --- .../src/org/jetbrains/dukat/js/type/analysis/expression.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 580a315d5..2b981433f 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -265,7 +265,7 @@ fun ExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathW is FunctionDeclaration -> this.addTo(owner) ?: NoTypeConstraint is ClassDeclaration -> this.addTo(owner, path) ?: NoTypeConstraint is IdentifierExpressionDeclaration -> owner[this] ?: ReferenceConstraint(this.identifier, owner) - is PropertyAccessExpressionDeclaration -> owner[this, path] ?: CompositeConstraint(owner) //TODO replace this with a reference constraint (of some sort) + is PropertyAccessExpressionDeclaration -> owner[this, path] ?: CompositeConstraint(owner) is BinaryExpressionDeclaration -> this.calculateConstraints(owner, path) is UnaryExpressionDeclaration -> this.calculateConstraints(owner, path) is TypeOfExpressionDeclaration -> this.calculateConstraints(owner, path) From 68f6726cac3abba142b94f87a3d7c5a9ba74a8c8 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Dec 2019 15:53:30 +0100 Subject: [PATCH 116/172] Unify ExportResolver and EnvironmentProvider into TypeAnalysisContext --- .../js/type/analysis/calculateConstraints.kt | 1 - .../dukat/js/type/analysis/introduceTypes.kt | 35 +++++++++++-------- .../js/type/analysis/resolveConstraints.kt | 9 +++++ .../type/export_resolution/BasicJSContext.kt | 18 ++++++++++ ...JSExportResolver.kt => CommonJSContext.kt} | 23 +++++++++--- .../CommonJSEnvironmentProvider.kt | 19 ---------- .../DefaultEnvironmentProvider.kt | 9 ----- .../export_resolution/EnvironmentProvider.kt | 7 ---- .../GeneralExportResolver.kt | 14 -------- ...portResolver.kt => TypeAnalysisContext.kt} | 8 +++-- 10 files changed, 70 insertions(+), 73 deletions(-) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/resolveConstraints.kt create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/BasicJSContext.kt rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/{CommonJSExportResolver.kt => CommonJSContext.kt} (63%) delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSEnvironmentProvider.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/DefaultEnvironmentProvider.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EnvironmentProvider.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/{ExportResolver.kt => TypeAnalysisContext.kt} (54%) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt index b9e101f6f..da7bed3d6 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt @@ -1,7 +1,6 @@ package org.jetbrains.dukat.js.type.analysis import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index 5171ffd06..d8ab00913 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -1,32 +1,37 @@ package org.jetbrains.dukat.js.type.analysis -import org.jetbrains.dukat.js.type.export_resolution.CommonJSEnvironmentProvider -import org.jetbrains.dukat.js.type.export_resolution.CommonJSExportResolver -import org.jetbrains.dukat.js.type.export_resolution.EnvironmentProvider -import org.jetbrains.dukat.js.type.export_resolution.ExportResolver +import org.jetbrains.dukat.js.type.export_resolution.CommonJSContext +import org.jetbrains.dukat.js.type.export_resolution.TypeAnalysisContext +import org.jetbrains.dukat.js.type.property_owner.Scope import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ModuleDeclaration import org.jetbrains.dukat.tsmodel.SourceFileDeclaration import org.jetbrains.dukat.tsmodel.SourceSetDeclaration -fun ModuleDeclaration.introduceTypes(environmentProvider: EnvironmentProvider, exportResolver: ExportResolver) : ModuleDeclaration { - val env = environmentProvider.getEnvironment() +private fun ModuleDeclaration.collectConstraints(context: TypeAnalysisContext): Scope { + val environment = context.getEnvironment() + val pathWalker = PathWalker() - calculateConstraints(env, pathWalker) + + calculateConstraints(environment, pathWalker) if (pathWalker.startNextPath()) { - //TODO check other paths raiseConcern("Conditional at top level not allowed!") { } } - val declarations = exportResolver.resolve(env) - return copy(declarations = declarations) + return environment } -fun SourceFileDeclaration.introduceTypes(environmentProvider: EnvironmentProvider, exportResolver: ExportResolver): SourceFileDeclaration { - return copy(root = root.introduceTypes(environmentProvider, exportResolver)) +fun ModuleDeclaration.introduceTypes(context: TypeAnalysisContext) : ModuleDeclaration { + val environment = collectConstraints(context) + + environment.resolveConstraints() + + val declarations = context.getExportsFrom(environment) + + return copy(declarations = declarations) } -fun SourceSetDeclaration.introduceTypes(environmentProvider: EnvironmentProvider = CommonJSEnvironmentProvider(), exportResolver: ExportResolver = CommonJSExportResolver()): SourceSetDeclaration { - return copy(sources = sources.map { it.introduceTypes(environmentProvider, exportResolver) }) -} \ No newline at end of file +fun SourceFileDeclaration.introduceTypes(context: TypeAnalysisContext) = copy(root = root.introduceTypes(context)) + +fun SourceSetDeclaration.introduceTypes(context: TypeAnalysisContext = CommonJSContext()) = copy(sources = sources.map { it.introduceTypes(context) }) \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/resolveConstraints.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/resolveConstraints.kt new file mode 100644 index 000000000..67a5638f1 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/resolveConstraints.kt @@ -0,0 +1,9 @@ +package org.jetbrains.dukat.js.type.analysis + +import org.jetbrains.dukat.js.type.property_owner.Scope + +fun Scope.resolveConstraints() { + propertyNames.forEach { + this[it] = this[it].resolve() + } +} diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/BasicJSContext.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/BasicJSContext.kt new file mode 100644 index 000000000..10792c59f --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/BasicJSContext.kt @@ -0,0 +1,18 @@ +package org.jetbrains.dukat.js.type.export_resolution + +import org.jetbrains.dukat.js.type.constraint.resolution.toDeclaration +import org.jetbrains.dukat.js.type.property_owner.Scope +import org.jetbrains.dukat.tsmodel.TopLevelDeclaration + +class BasicJSContext : TypeAnalysisContext { + override fun getEnvironment(): Scope { + return Scope(null) + } + + override fun getExportsFrom(environment: Scope) : List { + return environment.propertyNames.mapNotNull { propertyName -> + val resolvedConstraint = environment[propertyName] + resolvedConstraint.toDeclaration(propertyName) + } + } +} diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSExportResolver.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt similarity index 63% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSExportResolver.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt index c1edd04a7..72a56f5fb 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSExportResolver.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt @@ -5,17 +5,30 @@ import org.jetbrains.dukat.js.type.property_owner.Scope import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.TopLevelDeclaration -class CommonJSExportResolver : ExportResolver { - private val generalExportResolver = GeneralExportResolver() +class CommonJSContext : TypeAnalysisContext { + private val basicContext = BasicJSContext() - override fun resolve(scope: Scope): List { - val moduleObject = scope["module"].resolve() + override fun getEnvironment(): Scope { + val env = basicContext.getEnvironment() + + val moduleObject = ObjectConstraint(env) + val exportsObject = ObjectConstraint(env) + + moduleObject["exports"] = exportsObject + env["module"] = moduleObject + env["exports"] = exportsObject + + return env + } + + override fun getExportsFrom(environment: Scope): List { + val moduleObject = environment["module"] if (moduleObject is ObjectConstraint) { val exportsObject = moduleObject["exports"] if (exportsObject != null) { - return generalExportResolver.resolve( + return basicContext.getExportsFrom( Scope(null).apply { if (exportsObject is ObjectConstraint) { exportsObject.propertyNames.forEach { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSEnvironmentProvider.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSEnvironmentProvider.kt deleted file mode 100644 index 77ae7acb1..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSEnvironmentProvider.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.jetbrains.dukat.js.type.export_resolution - -import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint -import org.jetbrains.dukat.js.type.property_owner.Scope - -class CommonJSEnvironmentProvider : EnvironmentProvider { - override fun getEnvironment(): Scope { - val env = DefaultEnvironmentProvider().getEnvironment() - - val moduleObject = ObjectConstraint(env) - val exportsObject = ObjectConstraint(env) - - moduleObject["exports"] = exportsObject - env["module"] = moduleObject - env["exports"] = exportsObject - - return env - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/DefaultEnvironmentProvider.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/DefaultEnvironmentProvider.kt deleted file mode 100644 index 543aac081..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/DefaultEnvironmentProvider.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.jetbrains.dukat.js.type.export_resolution - -import org.jetbrains.dukat.js.type.property_owner.Scope - -class DefaultEnvironmentProvider : EnvironmentProvider { - override fun getEnvironment(): Scope { - return Scope(null) - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EnvironmentProvider.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EnvironmentProvider.kt deleted file mode 100644 index 88271e9f8..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/EnvironmentProvider.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.jetbrains.dukat.js.type.export_resolution - -import org.jetbrains.dukat.js.type.property_owner.Scope - -interface EnvironmentProvider { - fun getEnvironment(): Scope -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt deleted file mode 100644 index 82242b9d4..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/GeneralExportResolver.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.jetbrains.dukat.js.type.export_resolution - -import org.jetbrains.dukat.js.type.constraint.resolution.toDeclaration -import org.jetbrains.dukat.js.type.property_owner.Scope -import org.jetbrains.dukat.tsmodel.TopLevelDeclaration - -class GeneralExportResolver : ExportResolver { - override fun resolve(scope: Scope) : List { - return scope.propertyNames.mapNotNull { propertyName -> - val resolvedConstraint = scope[propertyName].resolve() - resolvedConstraint.toDeclaration(propertyName) - } - } -} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/TypeAnalysisContext.kt similarity index 54% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/TypeAnalysisContext.kt index 4063cd269..471450ca8 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/ExportResolver.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/TypeAnalysisContext.kt @@ -3,6 +3,8 @@ package org.jetbrains.dukat.js.type.export_resolution import org.jetbrains.dukat.js.type.property_owner.Scope import org.jetbrains.dukat.tsmodel.TopLevelDeclaration -interface ExportResolver { - fun resolve(scope: Scope) : List -} \ No newline at end of file +interface TypeAnalysisContext { + fun getEnvironment(): Scope + + fun getExportsFrom(environment: Scope) : List +} From eddd8c7e8c1602cfd017fea42d1f20fe4d669e62 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Dec 2019 10:17:46 +0100 Subject: [PATCH 117/172] Fix modifications to reference not always being tracked --- .../javascript/object/modifyInFunction.d.kt | 29 +++++++++++++++++++ .../javascript/object/modifyInFunction.d.ts | 13 +++++++++ .../dukat/js/type/property_owner/Scope.kt | 3 +- 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 compiler/test/data/javascript/object/modifyInFunction.d.kt create mode 100644 compiler/test/data/javascript/object/modifyInFunction.d.ts diff --git a/compiler/test/data/javascript/object/modifyInFunction.d.kt b/compiler/test/data/javascript/object/modifyInFunction.d.kt new file mode 100644 index 000000000..1ac8c5f44 --- /dev/null +++ b/compiler/test/data/javascript/object/modifyInFunction.d.kt @@ -0,0 +1,29 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external object obj { + var x: Number + var y: Number +} + +external interface `T$0` { + var x: Number + var y: Number + var z: Number +} + +external fun withZ(value: Number): `T$0` \ No newline at end of file diff --git a/compiler/test/data/javascript/object/modifyInFunction.d.ts b/compiler/test/data/javascript/object/modifyInFunction.d.ts new file mode 100644 index 000000000..3d4342422 --- /dev/null +++ b/compiler/test/data/javascript/object/modifyInFunction.d.ts @@ -0,0 +1,13 @@ + +let obj = { + x: 0 + y: 0 +} + +function withZ(value) { + obj.z = --value + return obj +} + +module.exports.obj = obj +module.exports.withZ = withZ diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt index 7c34061b2..e11fbedc2 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt @@ -9,12 +9,13 @@ class Scope(override val owner: PropertyOwner?) : PropertyOwner { get() = properties.keys private val properties = LinkedHashMap() + private val references = LinkedHashMap() override fun set(name: String, data: Constraint) { properties[name] = data } override fun get(name: String): Constraint { - return properties[name] ?: ReferenceConstraint(IdentifierEntity(name), this) + return properties[name] ?: references.getOrPut(name) { ReferenceConstraint(IdentifierEntity(name), this) } } } \ No newline at end of file From 27e009c73627cb93c29389c5a36edac952378a41 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Dec 2019 10:59:00 +0100 Subject: [PATCH 118/172] Remove redundant test case --- .../test/data/javascript/object/modified.d.kt | 8 +------- .../test/data/javascript/object/modified.d.ts | 17 ++++------------- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/compiler/test/data/javascript/object/modified.d.kt b/compiler/test/data/javascript/object/modified.d.kt index 1648495a3..f4b2b7401 100644 --- a/compiler/test/data/javascript/object/modified.d.kt +++ b/compiler/test/data/javascript/object/modified.d.kt @@ -28,10 +28,4 @@ external interface `T$1` { var z: Number } -external fun get3DVector(): `T$1` - -external object obj { - var a: String -} - -external fun modObj() \ No newline at end of file +external fun get3DVector(): `T$1` \ No newline at end of file diff --git a/compiler/test/data/javascript/object/modified.d.ts b/compiler/test/data/javascript/object/modified.d.ts index 2163bf7d0..d35b76c30 100644 --- a/compiler/test/data/javascript/object/modified.d.ts +++ b/compiler/test/data/javascript/object/modified.d.ts @@ -1,9 +1,11 @@ function get2DVector() { - return { + let v = { x: 1, y: 1 } + + return v } function get3DVector() { @@ -14,16 +16,5 @@ function get3DVector() { return v2D } -var obj = { - a: "text" -} - -function modObj() { - obj.b = "text" -} - - module.exports.get2DVector = get2DVector -module.exports.get3DVector = get3DVector -module.exports.obj = obj -module.exports.modObj = modObj \ No newline at end of file +module.exports.get3DVector = get3DVector \ No newline at end of file From d1adb89ea030a95bf631df3e361f34b76b9bd51d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Dec 2019 10:59:56 +0100 Subject: [PATCH 119/172] Add test for modifying an object through a reference gotten from a function (rather than directly) --- .../object/modifyThroughReference.d.kt | 29 +++++++++++++++++++ .../object/modifyThroughReference.d.ts | 19 ++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 compiler/test/data/javascript/object/modifyThroughReference.d.kt create mode 100644 compiler/test/data/javascript/object/modifyThroughReference.d.ts diff --git a/compiler/test/data/javascript/object/modifyThroughReference.d.kt b/compiler/test/data/javascript/object/modifyThroughReference.d.kt new file mode 100644 index 000000000..1ac8c5f44 --- /dev/null +++ b/compiler/test/data/javascript/object/modifyThroughReference.d.kt @@ -0,0 +1,29 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external object obj { + var x: Number + var y: Number +} + +external interface `T$0` { + var x: Number + var y: Number + var z: Number +} + +external fun withZ(value: Number): `T$0` \ No newline at end of file diff --git a/compiler/test/data/javascript/object/modifyThroughReference.d.ts b/compiler/test/data/javascript/object/modifyThroughReference.d.ts new file mode 100644 index 000000000..f59992b71 --- /dev/null +++ b/compiler/test/data/javascript/object/modifyThroughReference.d.ts @@ -0,0 +1,19 @@ + +var obj = { + x: 0 + y: 0 +} + +function getObj() { + return obj +} + +function withZ(value) { + var thisObj = getObj() + thisObj.z = --value + + return thisObj +} + +module.exports.obj = obj +module.exports.withZ = withZ From 70ad3842b06b5dd20d58dc4f52b37d9675d79f15 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Dec 2019 11:34:05 +0100 Subject: [PATCH 120/172] Resolve constraints received from functions, in order to not modify the original function --- .../reference/PropertyOwnerReferenceConstraint.kt | 8 +++++--- .../constraint/reference/call/CallArgumentConstraint.kt | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt index 69ebd9253..8fbf6bb6b 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt @@ -22,12 +22,14 @@ abstract class PropertyOwnerReferenceConstraint(parent: PropertyOwner) : Propert * to apply properties to the resolved reference. */ protected fun Constraint.resolveWithProperties() : Constraint { - if(this is PropertyOwner) { + val copy = this.resolve() + + if(copy is PropertyOwner) { modifiedProperties.forEach { (name, constraint) -> - this[name] = constraint + copy[name] = constraint } } - return this.resolve() + return copy.resolve() } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt index 8ef1a8f6c..bd6237d20 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt @@ -16,7 +16,7 @@ class CallArgumentConstraint( return if (functionConstraint is FunctionConstraint) { if (functionConstraint.parameterConstraints.size > argumentNum) { - functionConstraint.parameterConstraints[argumentNum].second + functionConstraint.parameterConstraints[argumentNum].second.resolveAsInput() } else { CompositeConstraint(owner) } From 01283cb9f05e8aa3eec6de3dc4b8bc5a6c8a7652 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Thu, 5 Dec 2019 13:22:01 +0100 Subject: [PATCH 121/172] Add test for arrow functions --- .../test/data/javascript/function/arrow.d.kt | 20 +++++++++++++++++++ .../test/data/javascript/function/arrow.d.ts | 6 ++++++ 2 files changed, 26 insertions(+) create mode 100644 compiler/test/data/javascript/function/arrow.d.kt create mode 100644 compiler/test/data/javascript/function/arrow.d.ts diff --git a/compiler/test/data/javascript/function/arrow.d.kt b/compiler/test/data/javascript/function/arrow.d.kt new file mode 100644 index 000000000..328d8fbc1 --- /dev/null +++ b/compiler/test/data/javascript/function/arrow.d.kt @@ -0,0 +1,20 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun arrowShort(): String + +external fun arrowLong(): String \ No newline at end of file diff --git a/compiler/test/data/javascript/function/arrow.d.ts b/compiler/test/data/javascript/function/arrow.d.ts new file mode 100644 index 000000000..268d661ad --- /dev/null +++ b/compiler/test/data/javascript/function/arrow.d.ts @@ -0,0 +1,6 @@ + +module.exports.arrowShort = () => "-->" + +module.exports.arrowLong = () => { + return "======>" +} From 037c2b6613065b2695aba96235ab05a89ace0e72 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Thu, 5 Dec 2019 13:23:07 +0100 Subject: [PATCH 122/172] Add test for function with parameter with optional property --- .../arguments/optionalProperties.d.kt | 31 +++++++++++++++++++ .../arguments/optionalProperties.d.ts | 14 +++++++++ 2 files changed, 45 insertions(+) create mode 100644 compiler/test/data/javascript/arguments/optionalProperties.d.kt create mode 100644 compiler/test/data/javascript/arguments/optionalProperties.d.ts diff --git a/compiler/test/data/javascript/arguments/optionalProperties.d.kt b/compiler/test/data/javascript/arguments/optionalProperties.d.kt new file mode 100644 index 000000000..b1d927492 --- /dev/null +++ b/compiler/test/data/javascript/arguments/optionalProperties.d.kt @@ -0,0 +1,31 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface `T$0` { + var x: Number + var y: Number + var z: Number +} + +external interface `T$1` { + var x: Number + var y: Number +} + +external fun lengthOf(vector: `T$0`): Any? + +external fun lengthOf(vector: `T$1`): Any? \ No newline at end of file diff --git a/compiler/test/data/javascript/arguments/optionalProperties.d.ts b/compiler/test/data/javascript/arguments/optionalProperties.d.ts new file mode 100644 index 000000000..999deb26f --- /dev/null +++ b/compiler/test/data/javascript/arguments/optionalProperties.d.ts @@ -0,0 +1,14 @@ + +function is3D(vector) { + return vector.z !== undefined && vector.z !== null +} + +module.exports.lengthOf = function(vector) { + let lengthSquared = vector.x ** 2 + vector.y ** 2 + + if (is3D(vector)) { + lengthSquared += vector.z ** 2 + } + + return Math.sqrt(lengthSquared) +} From 0d126f84ab5cb9e61ff1cf24722a35cde7ce908e Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Fri, 6 Dec 2019 10:50:14 +0100 Subject: [PATCH 123/172] Merge function types with different parameter names --- .../javascript/function/asDifferentTypes.d.kt | 18 +++ .../javascript/function/asDifferentTypes.d.ts | 30 ++++ javascript/js-translator/build.gradle | 1 + .../dukat/js/translator/JavaScriptLowerer.kt | 6 +- .../dukat/tsLowerings/mergeUnions.kt | 128 ++++++++++++++++++ 5 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 compiler/test/data/javascript/function/asDifferentTypes.d.kt create mode 100644 compiler/test/data/javascript/function/asDifferentTypes.d.ts create mode 100644 typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeUnions.kt diff --git a/compiler/test/data/javascript/function/asDifferentTypes.d.kt b/compiler/test/data/javascript/function/asDifferentTypes.d.kt new file mode 100644 index 000000000..8a3fa6b2c --- /dev/null +++ b/compiler/test/data/javascript/function/asDifferentTypes.d.kt @@ -0,0 +1,18 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun getOperation(operator: Any?): dynamic /* Unit | (Number, Number) -> Number */ \ No newline at end of file diff --git a/compiler/test/data/javascript/function/asDifferentTypes.d.ts b/compiler/test/data/javascript/function/asDifferentTypes.d.ts new file mode 100644 index 000000000..92f951bc2 --- /dev/null +++ b/compiler/test/data/javascript/function/asDifferentTypes.d.ts @@ -0,0 +1,30 @@ + +module.exports.getOperation = (operator) => { + if (operator == "+") { + return (augend, addend) => { + return augend - -addend + } + } else if (operator == "-") { + return (minuend, subtrahend) => { + return minuend - subtrahend + } + } else if (operator == "*" ||operator == "*" || operator == "x") { + return (multiplicand, multiplier) => { + return multiplicand * multiplier + } + } else if (operator == "/") { + return (dividend, divisor) => { + return dividend / divisor + } + } else if (operator == "%") { + return (dividend, divisor) => { + return dividend % divisor + } + } else if (operator == "**" || operator == "^") { + return (base, exponent) => { + return base ** exponent + } + } else { + throw "Illegal Argument Exception" + } +} diff --git a/javascript/js-translator/build.gradle b/javascript/js-translator/build.gradle index 01aa57428..e216e58ba 100644 --- a/javascript/js-translator/build.gradle +++ b/javascript/js-translator/build.gradle @@ -6,6 +6,7 @@ dependencies { implementation(project(":ast-common")) implementation(project(":ast-model")) implementation(project(":js-type-analysis")) + implementation(project(":ts-lowerings")) implementation(project(":ts-model")) implementation(project(":ts-translator")) implementation(project(":module-name-resolver")) diff --git a/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt b/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt index aabd486a4..f4f8f8c9d 100644 --- a/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt +++ b/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt @@ -5,16 +5,18 @@ import org.jetbrains.dukat.astModel.SourceSetModel import org.jetbrains.dukat.js.type.analysis.introduceTypes import org.jetbrains.dukat.moduleNameResolver.ModuleNameResolver import org.jetbrains.dukat.ts.translator.TypescriptLowerer +import org.jetbrains.dukat.tsLowerings.mergeUnions import org.jetbrains.dukat.tsmodel.SourceSetDeclaration class JavaScriptLowerer(nameResolver: ModuleNameResolver) : TypescriptLowerer(nameResolver) { override fun lower(sourceSet: SourceSetDeclaration, stdLibSourceSet: SourceSetModel?, renameMap: Map, uidToFqNameMapper: MutableMap): SourceSetModel { return super.lower( sourceSet - .introduceTypes(), + .introduceTypes() + .mergeUnions(), stdLibSourceSet, renameMap, uidToFqNameMapper ) } -} \ No newline at end of file +} diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeUnions.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeUnions.kt new file mode 100644 index 000000000..bf98e36a8 --- /dev/null +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeUnions.kt @@ -0,0 +1,128 @@ +package org.jetbrains.dukat.tsLowerings + +import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration +import org.jetbrains.dukat.tsmodel.ClassDeclaration +import org.jetbrains.dukat.tsmodel.ConstructorDeclaration +import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.MemberDeclaration +import org.jetbrains.dukat.tsmodel.ModuleDeclaration +import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.SourceFileDeclaration +import org.jetbrains.dukat.tsmodel.SourceSetDeclaration +import org.jetbrains.dukat.tsmodel.TopLevelDeclaration +import org.jetbrains.dukat.tsmodel.VariableDeclaration +import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration +import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration +import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration +import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration + +private fun FunctionTypeDeclaration.removeParameterNames() = copy( + parameters = parameters.map { it.copy(name = "") } +) + +private fun List.mergeFunctionTypes() : List { + val groups = groupBy { it.removeParameterNames() } + + return groups.map { (combination, functions) -> + if (functions.size == 1) { + functions[0] + } else { + //TODO check if the names are all the same, in which case removing them isn't necessary + combination + } + } +} + +private fun List.mergeObjectTypes() : List { + return this +} + +private fun UnionTypeDeclaration.mergeUnion() : ParameterValueDeclaration { + val types = mutableListOf() + val functionTypes = mutableListOf() + val objectTypes = mutableListOf() + + params.forEach { + when (it) { + is FunctionTypeDeclaration -> functionTypes.add(it) + is ObjectLiteralDeclaration -> objectTypes.add(it) + else -> types.add(it) + } + } + + types.addAll(functionTypes.mergeFunctionTypes()) + types.addAll(objectTypes.mergeObjectTypes()) + + return when (types.size) { + 1 -> types[0] + else -> UnionTypeDeclaration(types) + } +} + +private fun ParameterValueDeclaration.mergeUnions() : ParameterValueDeclaration { + return when (this) { + is FunctionTypeDeclaration -> this.mergeUnions() + is UnionTypeDeclaration -> this.mergeUnion() + else -> this + } +} + +private fun ParameterDeclaration.mergeUnions() = copy( + type = type.mergeUnions() +) + +private fun ConstructorDeclaration.mergeUnions() = copy( + parameters = parameters.map { it.mergeUnions() } +) + +private fun CallSignatureDeclaration.mergeUnions() = copy( + parameters = parameters.map { it.mergeUnions() } +) + +private fun MemberDeclaration.mergeUnions() : MemberDeclaration { + return when (this) { + is ConstructorDeclaration -> this.mergeUnions() + is FunctionDeclaration -> this.mergeUnions() + is CallSignatureDeclaration -> this.mergeUnions() + else -> this + } +} + +private fun ClassDeclaration.mergeUnions() = copy( + members = members.map { it.mergeUnions() } +) + +private fun FunctionTypeDeclaration.mergeUnions() = copy( + parameters = parameters.map { it.mergeUnions() }, + type = type.mergeUnions() +) + +private fun FunctionDeclaration.mergeUnions() = copy( + parameters = parameters.map { it.mergeUnions() }, + type = type.mergeUnions() +) + +private fun VariableDeclaration.mergeUnions() = copy( + type = type.mergeUnions() +) + +private fun TopLevelDeclaration.mergeUnions() : TopLevelDeclaration { + return when (this) { + is ClassDeclaration -> this.mergeUnions() + is FunctionDeclaration -> this.mergeUnions() + is VariableDeclaration -> this.mergeUnions() + else -> this + } +} + +fun ModuleDeclaration.mergeUnions() = copy( + declarations = declarations.map { it.mergeUnions() } +) + +fun SourceFileDeclaration.mergeUnions() = copy( + root = root.mergeUnions() +) + +fun SourceSetDeclaration.mergeUnions() = copy( + sources = sources.map { it.mergeUnions() } +) \ No newline at end of file From bd2853671ebb39cddfbd18fc8d16b2e9ec0200f6 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Fri, 6 Dec 2019 11:56:31 +0100 Subject: [PATCH 124/172] Add throw statement --- typescript/ts-converter/src/AstConverter.ts | 29 +++++++------------ typescript/ts-converter/src/ast/AstFactory.ts | 11 +++++++ .../ts-model-proto/src/Declarations.proto | 11 +++++-- .../tsmodel/ThrowStatementDeclaration.kt | 5 ++++ .../dukat/tsmodel/factory/convertProtobuf.kt | 11 +++++++ 5 files changed, 46 insertions(+), 21 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ThrowStatementDeclaration.kt diff --git a/typescript/ts-converter/src/AstConverter.ts b/typescript/ts-converter/src/AstConverter.ts index 04ce1e7e9..912138a16 100644 --- a/typescript/ts-converter/src/AstConverter.ts +++ b/typescript/ts-converter/src/AstConverter.ts @@ -781,6 +781,8 @@ export class AstConverter { ) } + //TODO convert other iteration statements than while statement + return decl } @@ -814,18 +816,10 @@ export class AstConverter { this.astExpressionConverter.convertExpression(statement.expression) )); } else if (ts.isIfStatement(statement)) { - let elseStatement; - - if (statement.elseStatement) { - elseStatement = this.convertTopLevelStatement(statement.elseStatement) - } else { - elseStatement = null - } - res.push(this.astFactory.createIfStatement( this.astExpressionConverter.convertExpression(statement.expression), this.convertTopLevelStatement(statement.thenStatement), - elseStatement + statement.elseStatement ? this.convertTopLevelStatement(statement.elseStatement) : null )) } else if (ts.isIterationStatement(statement)) { let iterationStatement = this.convertIterationStatement(statement); @@ -833,20 +827,19 @@ export class AstConverter { if (iterationStatement) { res.push(iterationStatement) } + } else if (ts.isReturnStatement(statement)) { + res.push(this.astFactory.createReturnStatement( + statement.expression ? this.astExpressionConverter.convertExpression(statement.expression) : null + )); + } else if (ts.isThrowStatement(statement)) { + res.push(this.astFactory.createThrowStatement( + statement.expression ? this.astExpressionConverter.convertExpression(statement.expression) : null + )) } else if (ts.isBlock(statement)) { let block = this.convertBlockStatement(statement); if (block) { res.push(block) } - } else if (ts.isReturnStatement(statement)) { - let expression : Expression | null = null; - if (statement.expression) { - expression = this.astExpressionConverter.convertExpression(statement.expression) - } - - res.push(this.astFactory.createReturnStatement( - expression - )); } else if (ts.isTypeAliasDeclaration(statement)) { if (ts.isTypeLiteralNode(statement.type)) { res.push(this.convertTypeLiteralToInterfaceDeclaration( diff --git a/typescript/ts-converter/src/ast/AstFactory.ts b/typescript/ts-converter/src/ast/AstFactory.ts index 0770068a8..0c7eea63b 100644 --- a/typescript/ts-converter/src/ast/AstFactory.ts +++ b/typescript/ts-converter/src/ast/AstFactory.ts @@ -150,6 +150,17 @@ export class AstFactory implements AstFactory { return topLevelDeclaration; } + createThrowStatement(expression: Expression | null): Declaration { + let throwStatement = new declarations.ThrowStatementDeclarationProto(); + if (expression) { + throwStatement.setExpression(expression); + } + + let topLevelDeclaration = new declarations.TopLevelDeclarationProto(); + topLevelDeclaration.setThrowstatement(throwStatement); + return topLevelDeclaration; + } + createBlockDeclaration(statements: Array): Block { let block = new declarations.BlockDeclarationProto(); block.setStatementsList(statements); diff --git a/typescript/ts-model-proto/src/Declarations.proto b/typescript/ts-model-proto/src/Declarations.proto index ac0da64c5..b6ac015ce 100644 --- a/typescript/ts-model-proto/src/Declarations.proto +++ b/typescript/ts-model-proto/src/Declarations.proto @@ -291,6 +291,10 @@ message ReturnStatementDeclarationProto { ExpressionDeclarationProto expression = 1; } +message ThrowStatementDeclarationProto { + ExpressionDeclarationProto expression = 1; +} + message ParameterDeclarationProto { string name = 1; ParameterValueDeclarationProto type = 2; @@ -363,9 +367,10 @@ message TopLevelDeclarationProto { ImportEqualsDeclarationProto importEquals = 9; ExpressionStatementDeclarationProto expressionStatement = 10; ReturnStatementDeclarationProto returnStatement = 11; - BlockDeclarationProto blockStatement = 12; - IfStatementDeclarationProto ifStatement = 13; - WhileStatementDeclarationProto whileStatement = 14; + ThrowStatementDeclarationProto throwStatement = 12; + BlockDeclarationProto blockStatement = 13; + IfStatementDeclarationProto ifStatement = 14; + WhileStatementDeclarationProto whileStatement = 15; } } diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ThrowStatementDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ThrowStatementDeclaration.kt new file mode 100644 index 000000000..c0f935a83 --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/ThrowStatementDeclaration.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dukat.tsmodel + +data class ThrowStatementDeclaration( + val expression: ExpressionDeclaration? +) : TopLevelDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt index 0d32152ab..12c4dbd93 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/factory/convertProtobuf.kt @@ -31,6 +31,7 @@ import org.jetbrains.dukat.tsmodel.SourceBundleDeclaration import org.jetbrains.dukat.tsmodel.SourceFileDeclaration import org.jetbrains.dukat.tsmodel.SourceSetDeclaration import org.jetbrains.dukat.tsmodel.ThisTypeDeclaration +import org.jetbrains.dukat.tsmodel.ThrowStatementDeclaration import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.TypeAliasDeclaration import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration @@ -111,6 +112,7 @@ import org.jetbrains.dukat.tsmodelproto.SourceFileDeclarationProto import org.jetbrains.dukat.tsmodelproto.SourceBundleDeclarationProto import org.jetbrains.dukat.tsmodelproto.SourceSetDeclarationProto import org.jetbrains.dukat.tsmodelproto.StringLiteralExpressionDeclarationProto +import org.jetbrains.dukat.tsmodelproto.ThrowStatementDeclarationProto import org.jetbrains.dukat.tsmodelproto.TopLevelDeclarationProto import org.jetbrains.dukat.tsmodelproto.TypeAliasDeclarationProto import org.jetbrains.dukat.tsmodelproto.TypeOfExpressionDeclarationProto @@ -286,6 +288,14 @@ fun ReturnStatementDeclarationProto.convert(): ReturnStatementDeclaration { ) } +fun ThrowStatementDeclarationProto.convert(): ThrowStatementDeclaration { + return ThrowStatementDeclaration( + if(hasExpression()) { + expression.convert() + } else null + ) +} + fun TopLevelDeclarationProto.convert(): TopLevelDeclaration { return when { hasClassDeclaration() -> classDeclaration.convert() @@ -301,6 +311,7 @@ fun TopLevelDeclarationProto.convert(): TopLevelDeclaration { hasWhileStatement() -> whileStatement.convert() hasExpressionStatement() -> expressionStatement.convert() hasReturnStatement() -> returnStatement.convert() + hasThrowStatement() -> throwStatement.convert() hasBlockStatement() -> blockStatement.convert() else -> throw Exception("unknown TopLevelEntity: ${this}") } From 62b6422269fe3d7a86bfd2d7a89deae584eda4e3 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Fri, 6 Dec 2019 13:13:36 +0100 Subject: [PATCH 125/172] Track functions without ordinary return (by exception) --- .../dukat/js/type/analysis/calculateConstraints.kt | 8 ++++++++ .../js/type/constraint/composite/CompositeConstraint.kt | 2 -- .../js/type/constraint/composite/UnionTypeConstraint.kt | 4 ++-- .../type/constraint/immutable/resolved/ThrowConstraint.kt | 3 +++ .../type/constraint/resolution/constraintToDeclaration.kt | 3 +++ .../src/org/jetbrains/dukat/js/type/type/types.kt | 6 ++++++ 6 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ThrowConstraint.kt diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt index da7bed3d6..0c2d3c047 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt @@ -2,6 +2,7 @@ package org.jetbrains.dukat.js.type.analysis import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.ThrowConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.panic.raiseConcern @@ -13,6 +14,7 @@ import org.jetbrains.dukat.tsmodel.IfStatementDeclaration import org.jetbrains.dukat.tsmodel.InterfaceDeclaration import org.jetbrains.dukat.tsmodel.ModuleDeclaration import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration +import org.jetbrains.dukat.tsmodel.ThrowStatementDeclaration import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.WhileStatementDeclaration @@ -51,6 +53,11 @@ fun ReturnStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: return expression?.calculateConstraints(owner, path) ?: VoidTypeConstraint } +fun ThrowStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { + expression?.calculateConstraints(owner, path) + return ThrowConstraint +} + fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint? { when (this) { is FunctionDeclaration -> this.addTo(owner) @@ -61,6 +68,7 @@ fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWal is ExpressionStatementDeclaration -> this.calculateConstraints(owner, path) is BlockDeclaration -> return this.calculateConstraints(owner, path) is ReturnStatementDeclaration -> return this.calculateConstraints(owner, path) + is ThrowStatementDeclaration -> return this.calculateConstraints(owner, path) is InterfaceDeclaration, is ModuleDeclaration -> { /* These statements aren't supported in JS (ignore them) */ } else -> raiseConcern("Unexpected top level entity type <${this::class}>") { } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt index 78dd00ae3..55e561feb 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt @@ -7,7 +7,6 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstrain import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint -import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner @@ -64,7 +63,6 @@ class CompositeConstraint( resolvedConstraints.contains(BigIntTypeConstraint) -> BigIntTypeConstraint resolvedConstraints.contains(BooleanTypeConstraint) -> BooleanTypeConstraint resolvedConstraints.contains(StringTypeConstraint) -> StringTypeConstraint - resolvedConstraints.contains(RecursiveConstraint) -> RecursiveConstraint else -> NoTypeConstraint } } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt index 14d7092b1..9f466f0fb 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt @@ -4,13 +4,13 @@ import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.ThrowConstraint class UnionTypeConstraint( val types: List ) : ImmutableConstraint { override fun resolve(): Constraint { - val resolvedTypes = types.map { it.resolve() }.filter { it != RecursiveConstraint } + val resolvedTypes = types.map { it.resolve() }.filter { it != RecursiveConstraint && it != ThrowConstraint } return when (resolvedTypes.size) { 0 -> NoTypeConstraint diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ThrowConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ThrowConstraint.kt new file mode 100644 index 000000000..94c3bc415 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ThrowConstraint.kt @@ -0,0 +1,3 @@ +package org.jetbrains.dukat.js.type.constraint.immutable.resolved + +object ThrowConstraint : ResolvedConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index 73adf0b0b..ce9b6452c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -8,6 +8,7 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConst import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.ThrowConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint @@ -15,6 +16,7 @@ import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.js.type.type.anyNullableType import org.jetbrains.dukat.js.type.type.booleanType +import org.jetbrains.dukat.js.type.type.nothingType import org.jetbrains.dukat.js.type.type.numberType import org.jetbrains.dukat.js.type.type.stringType import org.jetbrains.dukat.js.type.type.voidType @@ -194,6 +196,7 @@ fun Constraint.toType() : ParameterValueDeclaration { is BooleanTypeConstraint -> booleanType is StringTypeConstraint -> stringType is VoidTypeConstraint -> voidType + is ThrowConstraint -> nothingType is UnionTypeConstraint -> this.toType() is ObjectConstraint -> this.toType() is FunctionConstraint -> this.toType() diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/type/types.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/type/types.kt index e3c08b672..70936f22c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/type/types.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/type/types.kt @@ -9,6 +9,12 @@ val voidType = TypeDeclaration( nullable = false ) +val nothingType = TypeDeclaration( + value = IdentifierEntity("Nothing"), + params = emptyList(), + nullable = false +) + val anyNullableType = TypeDeclaration( value = IdentifierEntity("any"), params = emptyList(), From 42e8e14639be88ac38ebfd710f463df847fdabd6 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Fri, 6 Dec 2019 13:39:45 +0100 Subject: [PATCH 126/172] Add tests for functions throwing errors --- .../test/data/javascript/throw/always.d.kt | 18 ++++++++++++++++++ .../test/data/javascript/throw/always.d.ts | 4 ++++ .../data/javascript/throw/onCondition.d.kt | 18 ++++++++++++++++++ .../data/javascript/throw/onCondition.d.ts | 8 ++++++++ 4 files changed, 48 insertions(+) create mode 100644 compiler/test/data/javascript/throw/always.d.kt create mode 100644 compiler/test/data/javascript/throw/always.d.ts create mode 100644 compiler/test/data/javascript/throw/onCondition.d.kt create mode 100644 compiler/test/data/javascript/throw/onCondition.d.ts diff --git a/compiler/test/data/javascript/throw/always.d.kt b/compiler/test/data/javascript/throw/always.d.kt new file mode 100644 index 000000000..cf9c16621 --- /dev/null +++ b/compiler/test/data/javascript/throw/always.d.kt @@ -0,0 +1,18 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun error(value: Any?): Nothing \ No newline at end of file diff --git a/compiler/test/data/javascript/throw/always.d.ts b/compiler/test/data/javascript/throw/always.d.ts new file mode 100644 index 000000000..b4c1ec386 --- /dev/null +++ b/compiler/test/data/javascript/throw/always.d.ts @@ -0,0 +1,4 @@ + +module.exports.error = (value) => { + throw value +} diff --git a/compiler/test/data/javascript/throw/onCondition.d.kt b/compiler/test/data/javascript/throw/onCondition.d.kt new file mode 100644 index 000000000..206e66a3d --- /dev/null +++ b/compiler/test/data/javascript/throw/onCondition.d.kt @@ -0,0 +1,18 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun assertNotNull(value: Any?, lazyMessage: Any?): Any? \ No newline at end of file diff --git a/compiler/test/data/javascript/throw/onCondition.d.ts b/compiler/test/data/javascript/throw/onCondition.d.ts new file mode 100644 index 000000000..f65aca2e1 --- /dev/null +++ b/compiler/test/data/javascript/throw/onCondition.d.ts @@ -0,0 +1,8 @@ + +module.exports.assertNotNull = (value, lazyMessage) => { + if (value === void 0 || value === null) { + throw Error(lazyMessage()) + } + + return value +} From 76d2775e93f1d70f695bcd1998f7864747d8a249 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Mon, 9 Dec 2019 18:45:42 +0100 Subject: [PATCH 127/172] Track invocation of arguments, and the types of the return values of those invocations --- .../arguments/callResultModified.d.kt | 33 ++++++++++ .../arguments/callResultModified.d.ts | 8 +++ .../data/javascript/arguments/callable.d.kt | 18 +++++ .../data/javascript/arguments/callable.d.ts | 7 ++ .../data/javascript/throw/onCondition.d.kt | 2 +- .../data/javascript/throw/onCondition.d.ts | 4 +- .../dukat/js/type/analysis/expression.kt | 18 ++--- .../dukat/js/type/constraint/Constraint.kt | 17 ++--- .../composite/CompositeConstraint.kt | 66 +++++++++++++------ .../composite/UnionTypeConstraint.kt | 4 +- .../immutable/CallableConstraint.kt | 24 +++++++ .../immutable/ImmutableConstraint.kt | 2 - .../immutable/resolved/ResolvedConstraint.kt | 2 +- .../constraint/properties/ClassConstraint.kt | 2 +- .../properties/FunctionConstraint.kt | 12 ++-- .../constraint/properties/ObjectConstraint.kt | 13 ++-- .../PropertyOwnerReferenceConstraint.kt | 1 - .../reference/ReferenceConstraint.kt | 2 +- .../reference/call/CallArgumentConstraint.kt | 12 ++-- .../reference/call/CallResultConstraint.kt | 2 +- .../resolution/constraintToDeclaration.kt | 16 ++++- 21 files changed, 187 insertions(+), 78 deletions(-) create mode 100644 compiler/test/data/javascript/arguments/callResultModified.d.kt create mode 100644 compiler/test/data/javascript/arguments/callResultModified.d.ts create mode 100644 compiler/test/data/javascript/arguments/callable.d.kt create mode 100644 compiler/test/data/javascript/arguments/callable.d.ts create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/CallableConstraint.kt diff --git a/compiler/test/data/javascript/arguments/callResultModified.d.kt b/compiler/test/data/javascript/arguments/callResultModified.d.kt new file mode 100644 index 000000000..430cb0b29 --- /dev/null +++ b/compiler/test/data/javascript/arguments/callResultModified.d.kt @@ -0,0 +1,33 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface `T$0` { + var x: Number + var y: Number + var z: Number +} + +external interface `T$1` { + var x: Number + var y: Number + var z: Number + var negative: Any? + get() = definedExternally + set(value) = definedExternally +} + +external fun generateVector(vectorProvider: (`0`: Any? /* = null */, `1`: Any? /* = null */, `2`: Any? /* = null */) -> dynamic): `T$1` \ No newline at end of file diff --git a/compiler/test/data/javascript/arguments/callResultModified.d.ts b/compiler/test/data/javascript/arguments/callResultModified.d.ts new file mode 100644 index 000000000..6665eb3a0 --- /dev/null +++ b/compiler/test/data/javascript/arguments/callResultModified.d.ts @@ -0,0 +1,8 @@ + +module.exports.generateVector = (vectorProvider) => { + let vector = vectorProvider(0, 0, 0) + + vector.negative = vectorProvider(-vector.x, -vector.y, -vector.z) + + return vector +} diff --git a/compiler/test/data/javascript/arguments/callable.d.kt b/compiler/test/data/javascript/arguments/callable.d.kt new file mode 100644 index 000000000..2f056ba82 --- /dev/null +++ b/compiler/test/data/javascript/arguments/callable.d.kt @@ -0,0 +1,18 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun runOperation(numA: Number, numB: Number, operation: (`0`: Any? /* = null */, `1`: Any? /* = null */) -> Number): Number \ No newline at end of file diff --git a/compiler/test/data/javascript/arguments/callable.d.ts b/compiler/test/data/javascript/arguments/callable.d.ts new file mode 100644 index 000000000..88958179b --- /dev/null +++ b/compiler/test/data/javascript/arguments/callable.d.ts @@ -0,0 +1,7 @@ + +module.exports.runOperation = (numA, numB, operation) => { + numA = 0 - -numA + numB = 0 - -numB + + return 0 - -operation(numA, numB) +} diff --git a/compiler/test/data/javascript/throw/onCondition.d.kt b/compiler/test/data/javascript/throw/onCondition.d.kt index 206e66a3d..ff557d67b 100644 --- a/compiler/test/data/javascript/throw/onCondition.d.kt +++ b/compiler/test/data/javascript/throw/onCondition.d.kt @@ -15,4 +15,4 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun assertNotNull(value: Any?, lazyMessage: Any?): Any? \ No newline at end of file +external fun assertNotNull(value: Any?, message: Any?): Any? \ No newline at end of file diff --git a/compiler/test/data/javascript/throw/onCondition.d.ts b/compiler/test/data/javascript/throw/onCondition.d.ts index f65aca2e1..40e31828a 100644 --- a/compiler/test/data/javascript/throw/onCondition.d.ts +++ b/compiler/test/data/javascript/throw/onCondition.d.ts @@ -1,7 +1,7 @@ -module.exports.assertNotNull = (value, lazyMessage) => { +module.exports.assertNotNull = (value, message) => { if (value === void 0 || value === null) { - throw Error(lazyMessage()) + throw new Error(message) } return value diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 2b981433f..da6e391c5 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -5,6 +5,7 @@ import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.reference.ReferenceConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.CallableConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint @@ -21,12 +22,8 @@ import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint import org.jetbrains.dukat.js.type.property_owner.Scope import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ClassDeclaration -import org.jetbrains.dukat.tsmodel.ConstructorDeclaration import org.jetbrains.dukat.tsmodel.ExpressionDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration -import org.jetbrains.dukat.tsmodel.MemberDeclaration -import org.jetbrains.dukat.tsmodel.ModifierDeclaration -import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.expression.BinaryExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.CallExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.ConditionalExpressionDeclaration @@ -206,6 +203,7 @@ fun TypeOfExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { val callTargetConstraints = expression.calculateConstraints(owner, path) + var callResultConstraint: Constraint = CallResultConstraint(owner, callTargetConstraints) val argumentConstraints = arguments.map { it.calculateConstraints(owner, path) } argumentConstraints.forEachIndexed { argumentNumber, arg -> @@ -216,10 +214,14 @@ fun CallExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: P ) } - return CallResultConstraint( - owner, - callTargetConstraints - ) + if (callTargetConstraints is CompositeConstraint) { + callResultConstraint = CompositeConstraint(owner) + + //TODO add arguments to CallableConstraint + callTargetConstraints += CallableConstraint(argumentConstraints.size, callResultConstraint) + } + + return callResultConstraint } fun NewExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWalker) : Constraint { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt index 0dc7ffee0..6c8e9b25d 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/Constraint.kt @@ -9,24 +9,15 @@ interface Constraint { } } - /** - * Same as [resolve], but called instead, - * when resolving a constraint to get a type - * that can be used in a manner this constraint can. - * - * (For example, when passing an object to a - * function, and adding an "x" property to it, - * this resolution will not contain it, but - * [resolve] will) - */ - fun resolveAsInput() : Constraint - /** * Resolves all references and other constraints it contains, * to turn this constraint into one that represents a type. * * Should only be run after collecting all constraints, * and constraint should not be modified afterwards. + * + * When resolving as an input, resulting constraint + * won't contain properties added to this constraint. */ - fun resolve() : Constraint + fun resolve(resolveAsInput: Boolean = false): Constraint } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt index 55e561feb..bf04fb579 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt @@ -1,13 +1,15 @@ package org.jetbrains.dukat.js.type.constraint.composite import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.immutable.CallableConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint -import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint +import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint +import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class CompositeConstraint( @@ -55,31 +57,53 @@ class CompositeConstraint( } } - private fun resolveToBasicType() : Constraint { - val resolvedConstraints = getFlatConstraints().map { it.resolve() } + override fun resolve(resolveAsInput: Boolean) : Constraint { + val properties = if (resolveAsInput) neededProperties else allProperties - return when { - resolvedConstraints.contains(NumberTypeConstraint) -> NumberTypeConstraint - resolvedConstraints.contains(BigIntTypeConstraint) -> BigIntTypeConstraint - resolvedConstraints.contains(BooleanTypeConstraint) -> BooleanTypeConstraint - resolvedConstraints.contains(StringTypeConstraint) -> StringTypeConstraint - else -> NoTypeConstraint - } - } + val resolvedConstraints = getFlatConstraints().map { it.resolve(resolveAsInput) } + + val callableConstraints = resolvedConstraints.filterIsInstance() + + return if (properties.isNotEmpty() || callableConstraints.isNotEmpty()) { + var parameterCount = -1 - private fun resolveWithProperties(properties: Map, resolveConstraint: (Constraint) -> Constraint) : Constraint { - return if (properties.isNotEmpty()) { - ObjectConstraint(owner).apply { - properties.forEach { (name, value) -> - this[name] = resolveConstraint(value) + val callsCanBeUnified = callableConstraints.all { + if (parameterCount < 0) { + parameterCount = it.parameterCount } + + it.parameterCount == parameterCount } + + val resultConstraint: PropertyOwnerConstraint = if (callableConstraints.isNotEmpty() && callsCanBeUnified) { + FunctionConstraint( + owner, + UnionTypeConstraint( + callableConstraints.map { it.returnConstraints } + ), + List(parameterCount) { "`$it`" to NoTypeConstraint } + ) + } else { + ObjectConstraint(owner).apply { + callableConstraints.forEach { + callSignatureConstraints.add(it.resolve(resolveAsInput)) + } + } + } + + properties.forEach { (name, value) -> + resultConstraint[name] = value + } + + resultConstraint.resolve(resolveAsInput) } else { - resolveToBasicType() + when { + resolvedConstraints.contains(NumberTypeConstraint) -> NumberTypeConstraint + resolvedConstraints.contains(BigIntTypeConstraint) -> BigIntTypeConstraint + resolvedConstraints.contains(BooleanTypeConstraint) -> BooleanTypeConstraint + resolvedConstraints.contains(StringTypeConstraint) -> StringTypeConstraint + else -> NoTypeConstraint + } } } - - override fun resolve() = resolveWithProperties(allProperties, Constraint::resolve) - - override fun resolveAsInput() = resolveWithProperties(neededProperties, Constraint::resolveAsInput) } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt index 9f466f0fb..264d1c327 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt @@ -9,8 +9,8 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.ThrowConstraint class UnionTypeConstraint( val types: List ) : ImmutableConstraint { - override fun resolve(): Constraint { - val resolvedTypes = types.map { it.resolve() }.filter { it != RecursiveConstraint && it != ThrowConstraint } + override fun resolve(resolveAsInput: Boolean): Constraint { + val resolvedTypes = types.map { it.resolve(resolveAsInput) }.filter { it != RecursiveConstraint && it != ThrowConstraint } return when (resolvedTypes.size) { 0 -> NoTypeConstraint diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/CallableConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/CallableConstraint.kt new file mode 100644 index 000000000..8d65ee42d --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/CallableConstraint.kt @@ -0,0 +1,24 @@ +package org.jetbrains.dukat.js.type.constraint.immutable + +import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.resolution.ResolutionState + +class CallableConstraint( + val parameterCount: Int, + returnConstraints: Constraint +) : ImmutableConstraint { + var returnConstraints = returnConstraints + private set + + private var resolutionState: ResolutionState = ResolutionState.UNRESOLVED + + override fun resolve(resolveAsInput: Boolean): Constraint { + if (resolutionState == ResolutionState.UNRESOLVED) { + resolutionState = ResolutionState.RESOLVING + returnConstraints = returnConstraints.resolve(resolveAsInput) + resolutionState = ResolutionState.RESOLVED + } + + return this + } +} diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/ImmutableConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/ImmutableConstraint.kt index 02fa5bd75..7be85bfcf 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/ImmutableConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/ImmutableConstraint.kt @@ -4,6 +4,4 @@ import org.jetbrains.dukat.js.type.constraint.Constraint interface ImmutableConstraint : Constraint { override operator fun plusAssign(other: Constraint) { /* do nothing */ } - - override fun resolveAsInput() = resolve() } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ResolvedConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ResolvedConstraint.kt index dbcb559f6..b77fe8b69 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ResolvedConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/immutable/resolved/ResolvedConstraint.kt @@ -3,5 +3,5 @@ package org.jetbrains.dukat.js.type.constraint.immutable.resolved import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint interface ResolvedConstraint : ImmutableConstraint { - override fun resolve() = this + override fun resolve(resolveAsInput: Boolean) = this } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt index ba3464056..de2cb1fc0 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt @@ -23,7 +23,7 @@ class ClassConstraint(owner: PropertyOwner, prototype: ObjectConstraint = Object return staticMembers[name] } - override fun resolve(): ClassConstraint { + override fun resolve(resolveAsInput: Boolean): ClassConstraint { val constructorConstraint = constructorConstraint if (constructorConstraint != null) { this.constructorConstraint = constructorConstraint.resolve() diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt index a17dad3e8..3b599bc24 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt @@ -64,14 +64,14 @@ class FunctionConstraint( FunctionConstraint( owner, returnConstraints.resolve(), - parameterConstraints.map { (name, constraint) -> name to constraint.resolveAsInput() } + parameterConstraints.map { (name, constraint) -> name to constraint.resolve(resolveAsInput = true) } ) } else { if (hasNonStaticMembers()) { classRepresentation.constructorConstraint = FunctionConstraint( owner, returnConstraints.resolve(), - parameterConstraints.map { (name, constraint) -> name to constraint.resolveAsInput() } + parameterConstraints.map { (name, constraint) -> name to constraint.resolve(resolveAsInput = true) } ) classRepresentation.resolve() @@ -84,18 +84,18 @@ class FunctionConstraint( objectRepresentation[it] = classRepresentation[it]!! } - objectRepresentation.callSignatureConstraint = FunctionConstraint( + objectRepresentation.callSignatureConstraints.add(FunctionConstraint( owner, returnConstraints.resolve(), - parameterConstraints.map { (name, constraint) -> name to constraint.resolveAsInput() } - ) + parameterConstraints.map { (name, constraint) -> name to constraint.resolve(resolveAsInput = true) } + )) objectRepresentation.resolve() } } } - override fun resolve(): Constraint { + override fun resolve(resolveAsInput: Boolean): Constraint { return when (resolutionState) { ResolutionState.UNRESOLVED -> { resolutionState = ResolutionState.RESOLVING diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt index 695ba4f93..3b938ddb2 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt @@ -13,7 +13,7 @@ class ObjectConstraint( private val properties = LinkedHashMap() - var callSignatureConstraint: Constraint? = null + val callSignatureConstraints = mutableListOf() override fun set(name: String, data: Constraint) { properties[name] = data @@ -32,13 +32,13 @@ class ObjectConstraint( raiseConcern("Instantiating constraint which cannot be instantiated!") { null } } } else { - null + null //TODO make sure an unresolved class being instantiated works } } } } - override fun resolve(): ObjectConstraint { + override fun resolve(resolveAsInput: Boolean): ObjectConstraint { val resolvedConstraint = if (instantiatedClass == null) { ObjectConstraint(owner) } else { @@ -51,10 +51,9 @@ class ObjectConstraint( } } - val callSignatureConstraint = callSignatureConstraint - if (callSignatureConstraint != null) { - resolvedConstraint.callSignatureConstraint = callSignatureConstraint.resolve() - } + resolvedConstraint.callSignatureConstraints.addAll( + callSignatureConstraints.map { it.resolve() } + ) propertyNames.forEach { resolvedConstraint[it] = this[it]!!.resolve() diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt index 8fbf6bb6b..a4ae8c18c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt @@ -4,7 +4,6 @@ import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner -import org.jetbrains.dukat.panic.raiseConcern abstract class PropertyOwnerReferenceConstraint(parent: PropertyOwner) : PropertyOwnerConstraint(parent) { private val modifiedProperties = LinkedHashMap() diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt index e685b4c70..a60860cb7 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt @@ -44,7 +44,7 @@ open class ReferenceConstraint( } } - override fun resolve(): Constraint { + override fun resolve(resolveAsInput: Boolean): Constraint { return when (resolutionState) { ResolutionState.UNRESOLVED -> { resolvedConstraint = resolveInOwner(owner) ?: CompositeConstraint(owner) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt index bd6237d20..0793fc052 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt @@ -11,17 +11,13 @@ class CallArgumentConstraint( private val callTarget: Constraint, private val argumentNum: Int ) : ImmutableConstraint { - override fun resolve(): Constraint { + override fun resolve(resolveAsInput: Boolean): Constraint { val functionConstraint = callTarget.resolve() - return if (functionConstraint is FunctionConstraint) { - if (functionConstraint.parameterConstraints.size > argumentNum) { - functionConstraint.parameterConstraints[argumentNum].second.resolveAsInput() - } else { - CompositeConstraint(owner) - } + return if (functionConstraint is FunctionConstraint && functionConstraint.parameterConstraints.size > argumentNum) { + functionConstraint.parameterConstraints[argumentNum].second.resolve(resolveAsInput = true) } else { - CallArgumentConstraint(owner, functionConstraint, argumentNum) + CompositeConstraint(owner) } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt index f767a8665..8580fb366 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt @@ -9,7 +9,7 @@ class CallResultConstraint( owner: PropertyOwner, private val callTarget: Constraint ) : PropertyOwnerReferenceConstraint(owner) { - override fun resolve(): Constraint { + override fun resolve(resolveAsInput: Boolean): Constraint { val functionConstraint = callTarget.resolve() return if (functionConstraint is FunctionConstraint) { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index ce9b6452c..04967e360 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -4,8 +4,10 @@ import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.CallableConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NumberTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.ThrowConstraint @@ -87,6 +89,12 @@ fun FunctionConstraint.toCallSignature() = CallSignatureDeclaration( typeParameters = emptyList() ) +fun CallableConstraint.toCallSignature() = CallSignatureDeclaration( + parameters = List(parameterCount) { NoTypeConstraint.toParameterDeclaration("") }, + type = returnConstraints.toType(), + typeParameters = emptyList() +) + fun FunctionDeclaration.withStaticModifier(isStatic: Boolean) : FunctionDeclaration { return this.copy(modifiers = if (isStatic) STATIC_MODIFIERS else emptyList()) } @@ -159,9 +167,11 @@ fun UnionTypeConstraint.toType() : UnionTypeDeclaration { fun ObjectConstraint.mapMembers() : List { val members = mutableListOf() - val callSignatureConstraint = callSignatureConstraint - if (callSignatureConstraint is FunctionConstraint) { - members.add(callSignatureConstraint.toCallSignature()) + callSignatureConstraints.forEach { + when (it) { + is FunctionConstraint -> members.add(it.toCallSignature()) + is CallableConstraint -> members.add(it.toCallSignature()) + } } members.addAll( From 7a61c634131073e2b2baa47741c4829363d29462 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Thu, 12 Dec 2019 11:54:53 +0100 Subject: [PATCH 128/172] Fix default exports, nameing them after the converted resource. --- .../dukat/js/type/analysis/introduceTypes.kt | 2 +- .../resolution/constraintToDeclaration.kt | 77 ++++++++++++------- .../type/export_resolution/BasicJSContext.kt | 2 +- .../type/export_resolution/CommonJSContext.kt | 23 +++--- .../export_resolution/TypeAnalysisContext.kt | 2 +- 5 files changed, 64 insertions(+), 42 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index d8ab00913..77d1f3e2e 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -27,7 +27,7 @@ fun ModuleDeclaration.introduceTypes(context: TypeAnalysisContext) : ModuleDecla environment.resolveConstraints() - val declarations = context.getExportsFrom(environment) + val declarations = context.getExportsFrom(environment, resourceName) return copy(declarations = declarations) } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index 04967e360..ebb3fab5e 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -26,6 +26,7 @@ import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.ConstructorDeclaration +import org.jetbrains.dukat.tsmodel.ExportAssignmentDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.MemberDeclaration import org.jetbrains.dukat.tsmodel.ModifierDeclaration @@ -33,23 +34,25 @@ import org.jetbrains.dukat.tsmodel.ParameterDeclaration import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.TopLevelDeclaration import org.jetbrains.dukat.tsmodel.VariableDeclaration +import org.jetbrains.dukat.tsmodel.WithUidDeclaration import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration -val EXPORT_MODIFIERS = listOf(ModifierDeclaration.EXPORT_KEYWORD) -val STATIC_MODIFIERS = listOf(ModifierDeclaration.STATIC_KEYWORD) +private val DECLARE_MODIFIERS = listOf(ModifierDeclaration.DECLARE_KEYWORD) +private val EXPORT_MODIFIERS = listOf(ModifierDeclaration.EXPORT_KEYWORD) +private val STATIC_MODIFIERS = listOf(ModifierDeclaration.STATIC_KEYWORD) -fun getVariableDeclaration(name: String, type: ParameterValueDeclaration) = VariableDeclaration( +private fun getVariableDeclaration(name: String, type: ParameterValueDeclaration, exportModifiers: List) = VariableDeclaration( name = name, type = type, - modifiers = EXPORT_MODIFIERS, + modifiers = exportModifiers, initializer = null, uid = getUID() ) -fun getPropertyDeclaration(name: String, type: ParameterValueDeclaration, isStatic: Boolean) = PropertyDeclaration( +private fun getPropertyDeclaration(name: String, type: ParameterValueDeclaration, isStatic: Boolean) = PropertyDeclaration( name = name, initializer = null, type = type, @@ -58,7 +61,7 @@ fun getPropertyDeclaration(name: String, type: ParameterValueDeclaration, isStat modifiers = if (isStatic) STATIC_MODIFIERS else emptyList() ) -fun Constraint.toParameterDeclaration(name: String) = ParameterDeclaration( +private fun Constraint.toParameterDeclaration(name: String) = ParameterDeclaration( name = name, type = this.toType(), initializer = null, @@ -66,51 +69,51 @@ fun Constraint.toParameterDeclaration(name: String) = ParameterDeclaration( optional = false ) -fun FunctionConstraint.toDeclaration(name: String) = FunctionDeclaration( +private fun FunctionConstraint.toDeclaration(name: String, exportModifiers: List) = FunctionDeclaration( name = name, parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, type = returnConstraints.toType(), typeParameters = emptyList(), - modifiers = EXPORT_MODIFIERS, + modifiers = exportModifiers, body = null, uid = getUID() ) -fun FunctionConstraint.toConstructor() = ConstructorDeclaration( +private fun FunctionConstraint.toConstructor() = ConstructorDeclaration( parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, typeParameters = emptyList(), - modifiers = EXPORT_MODIFIERS, + modifiers = emptyList(), body = null ) -fun FunctionConstraint.toCallSignature() = CallSignatureDeclaration( +private fun FunctionConstraint.toCallSignature() = CallSignatureDeclaration( parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, type = returnConstraints.toType(), typeParameters = emptyList() ) -fun CallableConstraint.toCallSignature() = CallSignatureDeclaration( +private fun CallableConstraint.toCallSignature() = CallSignatureDeclaration( parameters = List(parameterCount) { NoTypeConstraint.toParameterDeclaration("") }, type = returnConstraints.toType(), typeParameters = emptyList() ) -fun FunctionDeclaration.withStaticModifier(isStatic: Boolean) : FunctionDeclaration { +private fun FunctionDeclaration.withStaticModifier(isStatic: Boolean) : FunctionDeclaration { return this.copy(modifiers = if (isStatic) STATIC_MODIFIERS else emptyList()) } -fun FunctionConstraint.toMemberDeclaration(name: String, isStatic: Boolean) : MemberDeclaration? { - return this.toDeclaration(name).withStaticModifier(isStatic) +private fun FunctionConstraint.toMemberDeclaration(name: String, isStatic: Boolean) : MemberDeclaration? { + return this.toDeclaration(name, EXPORT_MODIFIERS).withStaticModifier(isStatic) } -fun Constraint.toMemberDeclaration(name: String, isStatic: Boolean = false) : MemberDeclaration? { +private fun Constraint.toMemberDeclaration(name: String, isStatic: Boolean = false) : MemberDeclaration? { return when (this) { is FunctionConstraint -> this.toMemberDeclaration(name, isStatic) else -> getPropertyDeclaration(name, this.toType(), isStatic) } } -fun ClassConstraint.toDeclaration(name: String) : ClassDeclaration { +private fun ClassConstraint.toDeclaration(name: String, exportModifiers: List) : ClassDeclaration { val members = mutableListOf() val constructorConstraint = constructorConstraint @@ -146,25 +149,25 @@ fun ClassConstraint.toDeclaration(name: String) : ClassDeclaration { members = members, typeParameters = emptyList(), parentEntities = emptyList(), - modifiers = EXPORT_MODIFIERS, + modifiers = exportModifiers, uid = getUID() ) } -fun FunctionConstraint.toType() : FunctionTypeDeclaration { +private fun FunctionConstraint.toType() : FunctionTypeDeclaration { return FunctionTypeDeclaration( parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, type = returnConstraints.toType() ) } -fun UnionTypeConstraint.toType() : UnionTypeDeclaration { +private fun UnionTypeConstraint.toType() : UnionTypeDeclaration { return UnionTypeDeclaration( params = types.map { it.toType() } ) } -fun ObjectConstraint.mapMembers() : List { +private fun ObjectConstraint.mapMembers() : List { val members = mutableListOf() callSignatureConstraints.forEach { @@ -191,7 +194,7 @@ fun ObjectConstraint.mapMembers() : List { return members } -fun ObjectConstraint.toType() : ObjectLiteralDeclaration { +private fun ObjectConstraint.toType() : ObjectLiteralDeclaration { return ObjectLiteralDeclaration( members = mapMembers(), uid = getUID(), @@ -199,7 +202,7 @@ fun ObjectConstraint.toType() : ObjectLiteralDeclaration { ) } -fun Constraint.toType() : ParameterValueDeclaration { +private fun Constraint.toType() : ParameterValueDeclaration { return when (this) { is NumberTypeConstraint -> numberType is BigIntTypeConstraint -> numberType @@ -214,11 +217,29 @@ fun Constraint.toType() : ParameterValueDeclaration { } } -fun Constraint.toDeclaration(name: String) : TopLevelDeclaration? { +private fun Constraint.toDeclaration(name: String, exportModifiers: List) : TopLevelDeclaration? { return when (this) { - is ClassConstraint -> this.toDeclaration(name) - is FunctionConstraint -> this.toDeclaration(name) + is ClassConstraint -> this.toDeclaration(name, exportModifiers) + is FunctionConstraint -> this.toDeclaration(name, exportModifiers) is CompositeConstraint -> raiseConcern("Unexpected composited type for variable named '$name'. Should be resolved by this point!") { null } - else -> getVariableDeclaration(name, this.toType()) + else -> getVariableDeclaration(name, this.toType(), exportModifiers) } -} \ No newline at end of file +} + +fun Constraint.toDeclaration(name: String) = toDeclaration(name, EXPORT_MODIFIERS) + +fun Constraint.asDefaultToDeclarations(defaultExportName: String) : List { + val declaration = this.toDeclaration(defaultExportName, DECLARE_MODIFIERS) + + return if (declaration is WithUidDeclaration) { + val exportEqualsDeclaration = ExportAssignmentDeclaration( + declaration.uid, + true + ) + + listOf(exportEqualsDeclaration, declaration) + } else { + emptyList() + } +} + diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/BasicJSContext.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/BasicJSContext.kt index 10792c59f..b3ec7de89 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/BasicJSContext.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/BasicJSContext.kt @@ -9,7 +9,7 @@ class BasicJSContext : TypeAnalysisContext { return Scope(null) } - override fun getExportsFrom(environment: Scope) : List { + override fun getExportsFrom(environment: Scope, defaultExportName: String) : List { return environment.propertyNames.mapNotNull { propertyName -> val resolvedConstraint = environment[propertyName] resolvedConstraint.toDeclaration(propertyName) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt index 72a56f5fb..73d7d56f5 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt @@ -1,6 +1,7 @@ package org.jetbrains.dukat.js.type.export_resolution import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint +import org.jetbrains.dukat.js.type.constraint.resolution.asDefaultToDeclarations import org.jetbrains.dukat.js.type.property_owner.Scope import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.TopLevelDeclaration @@ -21,28 +22,28 @@ class CommonJSContext : TypeAnalysisContext { return env } - override fun getExportsFrom(environment: Scope): List { + override fun getExportsFrom(environment: Scope, defaultExportName: String): List { val moduleObject = environment["module"] if (moduleObject is ObjectConstraint) { val exportsObject = moduleObject["exports"] if (exportsObject != null) { - return basicContext.getExportsFrom( - Scope(null).apply { - if (exportsObject is ObjectConstraint) { + return if (exportsObject is ObjectConstraint) { + basicContext.getExportsFrom( + Scope(null).apply { exportsObject.propertyNames.forEach { this[it] = exportsObject[it]!! } - } else { - //TODO figure out what to do in this case - this["default"] = exportsObject - } - } - ) + }, + defaultExportName + ) + } else { + exportsObject.asDefaultToDeclarations(defaultExportName) + } } } - return raiseConcern("No exports found!") { emptyList() } + return raiseConcern("No exports found!") { emptyList() } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/TypeAnalysisContext.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/TypeAnalysisContext.kt index 471450ca8..0be54bfe6 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/TypeAnalysisContext.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/TypeAnalysisContext.kt @@ -6,5 +6,5 @@ import org.jetbrains.dukat.tsmodel.TopLevelDeclaration interface TypeAnalysisContext { fun getEnvironment(): Scope - fun getExportsFrom(environment: Scope) : List + fun getExportsFrom(environment: Scope, defaultExportName: String) : List } From dadeef8f2df8298c43d81b5dc2605e420041fc51 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Thu, 12 Dec 2019 11:55:22 +0100 Subject: [PATCH 129/172] Add test for default function export --- .../test/data/javascript/default/foo.d.kt | 19 +++++++++++++++++++ .../test/data/javascript/default/foo.d.ts | 4 ++++ 2 files changed, 23 insertions(+) create mode 100644 compiler/test/data/javascript/default/foo.d.kt create mode 100644 compiler/test/data/javascript/default/foo.d.ts diff --git a/compiler/test/data/javascript/default/foo.d.kt b/compiler/test/data/javascript/default/foo.d.kt new file mode 100644 index 000000000..6055ddf15 --- /dev/null +++ b/compiler/test/data/javascript/default/foo.d.kt @@ -0,0 +1,19 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +@JsModule("") +external fun foo(): String \ No newline at end of file diff --git a/compiler/test/data/javascript/default/foo.d.ts b/compiler/test/data/javascript/default/foo.d.ts new file mode 100644 index 000000000..6f2a8ba13 --- /dev/null +++ b/compiler/test/data/javascript/default/foo.d.ts @@ -0,0 +1,4 @@ + +module.exports = function foo() { + return "text" +} From ee1f5c6b97df08e43b0b97254ac1a86a724dcbb7 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Thu, 12 Dec 2019 14:06:30 +0100 Subject: [PATCH 130/172] Fix typescript header generation for typescript declaration protobuf --- typescript/ts-model-proto/build.gradle | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/typescript/ts-model-proto/build.gradle b/typescript/ts-model-proto/build.gradle index 3591a4187..f470182cb 100644 --- a/typescript/ts-model-proto/build.gradle +++ b/typescript/ts-model-proto/build.gradle @@ -33,6 +33,21 @@ task prepareNpmPackage(type: Copy) { yarn.dependsOn = [yarnSetup, prepareNpmPackage] +task moveGeneratedTS() { + doLast { + def tsDir = file("$targetMainDir/ts") + + if (tsDir.exists() && tsDir.isDirectory()) { + tsDir.eachFile { file -> + file.renameTo("$targetMainDir/js/${file.getName()}") + } + + // Cannot delete folder, since the 'compileJava' accesses it, for some reason + // tsDir.delete() + } + } +} + dependencies { implementation("com.google.protobuf:protobuf-java:${gradle.protobufImplementationVersion}") } @@ -68,6 +83,7 @@ protobuf { all().each { task -> if(task.name == 'generateProto') { task.dependsOn = [yarn] + task.finalizedBy(moveGeneratedTS) } task.builtins { From ff6f95043d60ed222a8e6e54912db4fe9c6c9fbd Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Thu, 12 Dec 2019 14:53:57 +0100 Subject: [PATCH 131/172] Fix test to properly analyze throw statement --- compiler/test/data/javascript/function/asDifferentTypes.d.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/test/data/javascript/function/asDifferentTypes.d.kt b/compiler/test/data/javascript/function/asDifferentTypes.d.kt index 8a3fa6b2c..b0ba56b4d 100644 --- a/compiler/test/data/javascript/function/asDifferentTypes.d.kt +++ b/compiler/test/data/javascript/function/asDifferentTypes.d.kt @@ -15,4 +15,4 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun getOperation(operator: Any?): dynamic /* Unit | (Number, Number) -> Number */ \ No newline at end of file +external fun getOperation(operator: Any?): dynamic (Number, Number) -> Number \ No newline at end of file From f260494ca9a6ce4e704244a598c7df391e5e6c48 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Thu, 12 Dec 2019 16:16:42 +0100 Subject: [PATCH 132/172] Remove unused code --- typescript/ts-model-proto/build.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/typescript/ts-model-proto/build.gradle b/typescript/ts-model-proto/build.gradle index f470182cb..870b2a47e 100644 --- a/typescript/ts-model-proto/build.gradle +++ b/typescript/ts-model-proto/build.gradle @@ -41,9 +41,6 @@ task moveGeneratedTS() { tsDir.eachFile { file -> file.renameTo("$targetMainDir/js/${file.getName()}") } - - // Cannot delete folder, since the 'compileJava' accesses it, for some reason - // tsDir.delete() } } } From b971ff60539fbda222457566b43b36aa011d520c Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Mon, 16 Dec 2019 14:01:12 +0100 Subject: [PATCH 133/172] Handle function with properties as default export properly --- .../dukat/js/type/export_resolution/CommonJSContext.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt index 73d7d56f5..d413cbbcc 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt @@ -29,7 +29,7 @@ class CommonJSContext : TypeAnalysisContext { val exportsObject = moduleObject["exports"] if (exportsObject != null) { - return if (exportsObject is ObjectConstraint) { + return if (exportsObject is ObjectConstraint && exportsObject.callSignatureConstraints.isEmpty()) { basicContext.getExportsFrom( Scope(null).apply { exportsObject.propertyNames.forEach { From b697c74ed560f35720fe5e44d4780a3a8995cf86 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Mon, 16 Dec 2019 14:03:35 +0100 Subject: [PATCH 134/172] Add test for function with properties as default export --- .../javascript/default/fooWithProperties.d.kt | 23 +++++++++++++++++++ .../javascript/default/fooWithProperties.d.ts | 8 +++++++ 2 files changed, 31 insertions(+) create mode 100644 compiler/test/data/javascript/default/fooWithProperties.d.kt create mode 100644 compiler/test/data/javascript/default/fooWithProperties.d.ts diff --git a/compiler/test/data/javascript/default/fooWithProperties.d.kt b/compiler/test/data/javascript/default/fooWithProperties.d.kt new file mode 100644 index 000000000..2d0a64b6e --- /dev/null +++ b/compiler/test/data/javascript/default/fooWithProperties.d.kt @@ -0,0 +1,23 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION") + +import kotlin.js.* +import kotlin.js.Json +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external object fooWithProperties { + @nativeInvoke + operator fun invoke(): String + var propertyA: String + var propertyB: Number +} \ No newline at end of file diff --git a/compiler/test/data/javascript/default/fooWithProperties.d.ts b/compiler/test/data/javascript/default/fooWithProperties.d.ts new file mode 100644 index 000000000..9795d990e --- /dev/null +++ b/compiler/test/data/javascript/default/fooWithProperties.d.ts @@ -0,0 +1,8 @@ + +module.exports = function foo() { + return "text" +} + +module.exports.propertyA = "text" + +module.exports.propertyB = 0.0 From 5c4ba7343ffbeb4f0c710037875e5600cc6f5f3e Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Mon, 16 Dec 2019 18:10:40 +0100 Subject: [PATCH 135/172] Merge basic types, so that comparison for more complex ones works correctly --- .../jetbrains/dukat/tsLowerings/mergeUnions.kt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeUnions.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeUnions.kt index bf98e36a8..8664a74b6 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeUnions.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeUnions.kt @@ -14,6 +14,7 @@ import org.jetbrains.dukat.tsmodel.VariableDeclaration import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration +import org.jetbrains.dukat.tsmodel.types.TypeDeclaration import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration private fun FunctionTypeDeclaration.removeParameterNames() = copy( @@ -34,24 +35,31 @@ private fun List.mergeFunctionTypes() : List.mergeObjectTypes() : List { - return this + return toSet().toList() //TODO check if this is enough +} + +private fun List.mergeTypeDeclarations() : List { + return toSet().toList() } private fun UnionTypeDeclaration.mergeUnion() : ParameterValueDeclaration { val types = mutableListOf() val functionTypes = mutableListOf() val objectTypes = mutableListOf() + val typeDeclarations = mutableListOf() params.forEach { when (it) { - is FunctionTypeDeclaration -> functionTypes.add(it) - is ObjectLiteralDeclaration -> objectTypes.add(it) - else -> types.add(it) + is FunctionTypeDeclaration -> functionTypes += it.mergeUnions() + is ObjectLiteralDeclaration -> objectTypes += it + is TypeDeclaration -> typeDeclarations += it + else -> types += it.mergeUnions() } } types.addAll(functionTypes.mergeFunctionTypes()) types.addAll(objectTypes.mergeObjectTypes()) + types.addAll(typeDeclarations.mergeTypeDeclarations()) return when (types.size) { 1 -> types[0] From f1092b56e8c13eab443e97f62c7644599cb2319d Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Tue, 17 Dec 2019 11:07:02 +0100 Subject: [PATCH 136/172] Fix test for lambda argument with different names --- compiler/test/data/javascript/function/asDifferentTypes.d.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/test/data/javascript/function/asDifferentTypes.d.kt b/compiler/test/data/javascript/function/asDifferentTypes.d.kt index b0ba56b4d..b72d503e4 100644 --- a/compiler/test/data/javascript/function/asDifferentTypes.d.kt +++ b/compiler/test/data/javascript/function/asDifferentTypes.d.kt @@ -15,4 +15,4 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun getOperation(operator: Any?): dynamic (Number, Number) -> Number \ No newline at end of file +external fun getOperation(operator: Any?): (Number, Number) -> Number \ No newline at end of file From 1d7341bc92d6c0f09e795e30f40f699b4b8e5b19 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Tue, 17 Dec 2019 16:03:47 +0100 Subject: [PATCH 137/172] Rename 'mergeUnions' to 'mergeDuplicates' --- .../dukat/js/translator/JavaScriptLowerer.kt | 4 +- .../{mergeUnions.kt => mergeDuplicates.kt} | 72 ++++++++++--------- 2 files changed, 39 insertions(+), 37 deletions(-) rename typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/{mergeUnions.kt => mergeDuplicates.kt} (57%) diff --git a/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt b/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt index fe912ae44..0b76f2444 100644 --- a/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt +++ b/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt @@ -5,7 +5,7 @@ import org.jetbrains.dukat.astModel.SourceSetModel import org.jetbrains.dukat.js.type.analysis.introduceTypes import org.jetbrains.dukat.moduleNameResolver.ModuleNameResolver import org.jetbrains.dukat.ts.translator.TypescriptLowerer -import org.jetbrains.dukat.tsLowerings.mergeUnions +import org.jetbrains.dukat.tsLowerings.mergeDuplicates import org.jetbrains.dukat.tsmodel.SourceSetDeclaration import org.jetrbains.dukat.nodeLowering.lowerings.FqNode @@ -14,7 +14,7 @@ class JavaScriptLowerer(nameResolver: ModuleNameResolver) : TypescriptLowerer(na return super.lower( sourceSet .introduceTypes() - .mergeUnions(), + .mergeDuplicates(), stdLibSourceSet, renameMap, uidToFqNameMapper diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeUnions.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates.kt similarity index 57% rename from typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeUnions.kt rename to typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates.kt index 8664a74b6..8e74087d0 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeUnions.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates.kt @@ -22,7 +22,9 @@ private fun FunctionTypeDeclaration.removeParameterNames() = copy( ) private fun List.mergeFunctionTypes() : List { - val groups = groupBy { it.removeParameterNames() } + val fixedFunctions = map { it.mergeDuplicates() } + + val groups = fixedFunctions.groupBy { it.removeParameterNames() } return groups.map { (combination, functions) -> if (functions.size == 1) { @@ -50,10 +52,10 @@ private fun UnionTypeDeclaration.mergeUnion() : ParameterValueDeclaration { params.forEach { when (it) { - is FunctionTypeDeclaration -> functionTypes += it.mergeUnions() + is FunctionTypeDeclaration -> functionTypes += it is ObjectLiteralDeclaration -> objectTypes += it is TypeDeclaration -> typeDeclarations += it - else -> types += it.mergeUnions() + else -> types += it.mergeDuplicates() } } @@ -67,70 +69,70 @@ private fun UnionTypeDeclaration.mergeUnion() : ParameterValueDeclaration { } } -private fun ParameterValueDeclaration.mergeUnions() : ParameterValueDeclaration { +private fun ParameterValueDeclaration.mergeDuplicates() : ParameterValueDeclaration { return when (this) { - is FunctionTypeDeclaration -> this.mergeUnions() + is FunctionTypeDeclaration -> this.mergeDuplicates() is UnionTypeDeclaration -> this.mergeUnion() else -> this } } -private fun ParameterDeclaration.mergeUnions() = copy( - type = type.mergeUnions() +private fun ParameterDeclaration.mergeDuplicates() = copy( + type = type.mergeDuplicates() ) -private fun ConstructorDeclaration.mergeUnions() = copy( - parameters = parameters.map { it.mergeUnions() } +private fun ConstructorDeclaration.mergeDuplicates() = copy( + parameters = parameters.map { it.mergeDuplicates() } ) -private fun CallSignatureDeclaration.mergeUnions() = copy( - parameters = parameters.map { it.mergeUnions() } +private fun CallSignatureDeclaration.mergeDuplicates() = copy( + parameters = parameters.map { it.mergeDuplicates() } ) -private fun MemberDeclaration.mergeUnions() : MemberDeclaration { +private fun MemberDeclaration.mergeDuplicates() : MemberDeclaration { return when (this) { - is ConstructorDeclaration -> this.mergeUnions() - is FunctionDeclaration -> this.mergeUnions() - is CallSignatureDeclaration -> this.mergeUnions() + is ConstructorDeclaration -> this.mergeDuplicates() + is FunctionDeclaration -> this.mergeDuplicates() + is CallSignatureDeclaration -> this.mergeDuplicates() else -> this } } -private fun ClassDeclaration.mergeUnions() = copy( - members = members.map { it.mergeUnions() } +private fun ClassDeclaration.mergeDuplicates() = copy( + members = members.map { it.mergeDuplicates() } ) -private fun FunctionTypeDeclaration.mergeUnions() = copy( - parameters = parameters.map { it.mergeUnions() }, - type = type.mergeUnions() +private fun FunctionTypeDeclaration.mergeDuplicates() = copy( + parameters = parameters.map { it.mergeDuplicates() }, + type = type.mergeDuplicates() ) -private fun FunctionDeclaration.mergeUnions() = copy( - parameters = parameters.map { it.mergeUnions() }, - type = type.mergeUnions() +private fun FunctionDeclaration.mergeDuplicates() = copy( + parameters = parameters.map { it.mergeDuplicates() }, + type = type.mergeDuplicates() ) -private fun VariableDeclaration.mergeUnions() = copy( - type = type.mergeUnions() +private fun VariableDeclaration.mergeDuplicates() = copy( + type = type.mergeDuplicates() ) -private fun TopLevelDeclaration.mergeUnions() : TopLevelDeclaration { +private fun TopLevelDeclaration.mergeDuplicates() : TopLevelDeclaration { return when (this) { - is ClassDeclaration -> this.mergeUnions() - is FunctionDeclaration -> this.mergeUnions() - is VariableDeclaration -> this.mergeUnions() + is ClassDeclaration -> this.mergeDuplicates() + is FunctionDeclaration -> this.mergeDuplicates() + is VariableDeclaration -> this.mergeDuplicates() else -> this } } -fun ModuleDeclaration.mergeUnions() = copy( - declarations = declarations.map { it.mergeUnions() } +fun ModuleDeclaration.mergeDuplicates() = copy( + declarations = declarations.map { it.mergeDuplicates() } ) -fun SourceFileDeclaration.mergeUnions() = copy( - root = root.mergeUnions() +fun SourceFileDeclaration.mergeDuplicates() = copy( + root = root.mergeDuplicates() ) -fun SourceSetDeclaration.mergeUnions() = copy( - sources = sources.map { it.mergeUnions() } +fun SourceSetDeclaration.mergeDuplicates() = copy( + sources = sources.map { it.mergeDuplicates() } ) \ No newline at end of file From c9586c07e8ee8205eca4585f5f3f19c330d13ab2 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Tue, 17 Dec 2019 16:04:59 +0100 Subject: [PATCH 138/172] Track different overloads of functions, rather than a single function with union types --- .../dukat/js/type/analysis/expression.kt | 31 +---- .../composite/CompositeConstraint.kt | 12 +- .../composite/UnionTypeConstraint.kt | 2 +- .../properties/FunctionConstraint.kt | 56 +++++--- .../reference/call/CallArgumentConstraint.kt | 23 +++- .../reference/call/CallResultConstraint.kt | 14 +- .../resolution/constraintToDeclaration.kt | 121 ++++++++++-------- .../type/export_resolution/BasicJSContext.kt | 6 +- 8 files changed, 147 insertions(+), 118 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index da6e391c5..1fd1e44a9 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -39,35 +39,11 @@ import org.jetbrains.dukat.tsmodel.expression.literal.ObjectLiteralExpressionDec import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDeclaration import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration -fun List.pack() : FunctionConstraint { - return if (size == 1) { - this[0] - } else { - val parameters = mutableListOf>>() - - forEach { - it.parameterConstraints.forEachIndexed { index, (name, constraint) -> - if (parameters.size <= index) { - parameters.add(index, name to mutableListOf()) - } - - parameters[index].second.add(constraint) - } - } - - FunctionConstraint( - this[0].owner, - returnConstraints = UnionTypeConstraint(map { it.returnConstraints }), - parameterConstraints = parameters.map { (name, constraints) -> name to UnionTypeConstraint(constraints) } - ) - } -} - fun FunctionDeclaration.addTo(owner: PropertyOwner) : FunctionConstraint? { return if (this.body != null) { val pathWalker = PathWalker() - val versions = mutableListOf() + val versions = mutableListOf() do { val functionScope = Scope(owner) @@ -82,14 +58,13 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) : FunctionConstraint? { val returnTypeConstraints = body!!.calculateConstraints(functionScope, pathWalker) ?: VoidTypeConstraint - versions.add(FunctionConstraint( - owner, + versions.add(FunctionConstraint.Version( returnConstraints = returnTypeConstraints, parameterConstraints = parameterConstraints )) } while (pathWalker.startNextPath()) - val functionConstraint = versions.pack() + val functionConstraint = FunctionConstraint(owner, versions) if (name != "") { owner[name] = functionConstraint diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt index bf04fb579..bf3421fe7 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt @@ -77,11 +77,13 @@ class CompositeConstraint( val resultConstraint: PropertyOwnerConstraint = if (callableConstraints.isNotEmpty() && callsCanBeUnified) { FunctionConstraint( - owner, - UnionTypeConstraint( - callableConstraints.map { it.returnConstraints } - ), - List(parameterCount) { "`$it`" to NoTypeConstraint } + owner = owner, + versions = callableConstraints.map { callable -> + FunctionConstraint.Version( + callable.returnConstraints, + List(parameterCount) { i -> "`$i`" to NoTypeConstraint } + ) + } ) } else { ObjectConstraint(owner).apply { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt index 264d1c327..0619fca55 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/UnionTypeConstraint.kt @@ -18,4 +18,4 @@ class UnionTypeConstraint( else -> UnionTypeConstraint(resolvedTypes) } } -} \ No newline at end of file +} diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt index 3b599bc24..1b90e4eb0 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt @@ -8,9 +8,14 @@ import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class FunctionConstraint( owner: PropertyOwner, + val versions: List +) : PropertyOwnerConstraint(owner) { + + data class Version( val returnConstraints: Constraint, val parameterConstraints: List> -) : PropertyOwnerConstraint(owner) { + ) + private val classRepresentation = ClassConstraint(owner) override fun set(name: String, data: Constraint) { @@ -25,6 +30,20 @@ class FunctionConstraint( private var resolutionState = ResolutionState.UNRESOLVED private var resolvedConstraint: Constraint? = null + private fun getParameterNames() : List { + val parameters = mutableListOf() + + versions.forEach { + it.parameterConstraints.forEachIndexed { index, (name, _) -> + if (parameters.size <= index) { + parameters.add(index, name) + } + } + } + + return parameters + } + private fun hasMembers() : Boolean { return if (classRepresentation.propertyNames.isNotEmpty()) { if (classRepresentation.propertyNames == setOf("prototype")) { @@ -59,21 +78,22 @@ class FunctionConstraint( } } + private fun getResolvedCallable() = FunctionConstraint( + owner, + versions.map { + Version( + it.returnConstraints.resolve(), + it.parameterConstraints.map { (name, constraint) -> name to constraint.resolve(resolveAsInput = true) } + ) + } + ) + private fun doResolve(): Constraint { return if (!hasMembers()) { - FunctionConstraint( - owner, - returnConstraints.resolve(), - parameterConstraints.map { (name, constraint) -> name to constraint.resolve(resolveAsInput = true) } - ) + getResolvedCallable() } else { if (hasNonStaticMembers()) { - classRepresentation.constructorConstraint = FunctionConstraint( - owner, - returnConstraints.resolve(), - parameterConstraints.map { (name, constraint) -> name to constraint.resolve(resolveAsInput = true) } - ) - + classRepresentation.constructorConstraint = getResolvedCallable() classRepresentation.resolve() } else { val objectRepresentation = ObjectConstraint(owner) @@ -84,11 +104,7 @@ class FunctionConstraint( objectRepresentation[it] = classRepresentation[it]!! } - objectRepresentation.callSignatureConstraints.add(FunctionConstraint( - owner, - returnConstraints.resolve(), - parameterConstraints.map { (name, constraint) -> name to constraint.resolve(resolveAsInput = true) } - )) + objectRepresentation.callSignatureConstraints.add(getResolvedCallable()) objectRepresentation.resolve() } @@ -108,8 +124,10 @@ class FunctionConstraint( ResolutionState.RESOLVING -> { FunctionConstraint( owner, - RecursiveConstraint, - parameterConstraints.map { (name, _) -> name to NoTypeConstraint } + listOf(Version( + returnConstraints = RecursiveConstraint, + parameterConstraints = getParameterNames().map { it to NoTypeConstraint } + )) ) } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt index 0793fc052..85f24c554 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt @@ -3,6 +3,7 @@ package org.jetbrains.dukat.js.type.constraint.reference.call import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint +import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner @@ -14,10 +15,24 @@ class CallArgumentConstraint( override fun resolve(resolveAsInput: Boolean): Constraint { val functionConstraint = callTarget.resolve() - return if (functionConstraint is FunctionConstraint && functionConstraint.parameterConstraints.size > argumentNum) { - functionConstraint.parameterConstraints[argumentNum].second.resolve(resolveAsInput = true) - } else { - CompositeConstraint(owner) + if (functionConstraint is FunctionConstraint) { + if (functionConstraint.versions.size == 1) { + val parameters = functionConstraint.versions[0].parameterConstraints + + if (parameters.size > argumentNum) { + return parameters[argumentNum].second.resolve(resolveAsInput = true) + } + } else { + return UnionTypeConstraint( + functionConstraint.versions.mapNotNull { + if (it.parameterConstraints.size > argumentNum) { + it.parameterConstraints[argumentNum].second.resolve(resolveAsInput = true) + } else null + } + ).resolve() + } } + + return CompositeConstraint(owner) } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt index 8580fb366..7b0107427 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt @@ -1,6 +1,8 @@ package org.jetbrains.dukat.js.type.constraint.reference.call import org.jetbrains.dukat.js.type.constraint.Constraint +import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint +import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.constraint.reference.PropertyOwnerReferenceConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner @@ -13,9 +15,17 @@ class CallResultConstraint( val functionConstraint = callTarget.resolve() return if (functionConstraint is FunctionConstraint) { - functionConstraint.returnConstraints.resolveWithProperties() + if (functionConstraint.versions.size == 1) { + functionConstraint.versions[0].returnConstraints.resolveWithProperties() + } else { + UnionTypeConstraint( + functionConstraint.versions.map { + it.returnConstraints.resolveWithProperties() + } + ).resolve() + } } else { - CallResultConstraint(owner, functionConstraint) + NoTypeConstraint } } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index ebb3fab5e..4ad41a7ef 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -44,10 +44,10 @@ private val DECLARE_MODIFIERS = listOf(ModifierDeclaration.DECLARE_KEYWORD) private val EXPORT_MODIFIERS = listOf(ModifierDeclaration.EXPORT_KEYWORD) private val STATIC_MODIFIERS = listOf(ModifierDeclaration.STATIC_KEYWORD) -private fun getVariableDeclaration(name: String, type: ParameterValueDeclaration, exportModifiers: List) = VariableDeclaration( +private fun getVariableDeclaration(name: String, type: ParameterValueDeclaration, modifiers: List) = VariableDeclaration( name = name, type = type, - modifiers = exportModifiers, + modifiers = modifiers, initializer = null, uid = getUID() ) @@ -69,28 +69,34 @@ private fun Constraint.toParameterDeclaration(name: String) = ParameterDeclarati optional = false ) -private fun FunctionConstraint.toDeclaration(name: String, exportModifiers: List) = FunctionDeclaration( - name = name, - parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, - type = returnConstraints.toType(), - typeParameters = emptyList(), - modifiers = exportModifiers, - body = null, - uid = getUID() -) +private fun FunctionConstraint.toDeclarations(name: String, modifiers: List) = versions.map { + FunctionDeclaration( + name = name, + parameters = it.parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, + type = it.returnConstraints.toType(), + typeParameters = emptyList(), + modifiers = modifiers, + body = null, + uid = getUID() + ) +} -private fun FunctionConstraint.toConstructor() = ConstructorDeclaration( - parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, - typeParameters = emptyList(), - modifiers = emptyList(), - body = null -) +private fun FunctionConstraint.toConstructors() = versions.map { + ConstructorDeclaration( + parameters = it.parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, + typeParameters = emptyList(), + modifiers = emptyList(), + body = null + ) +} -private fun FunctionConstraint.toCallSignature() = CallSignatureDeclaration( - parameters = parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, - type = returnConstraints.toType(), - typeParameters = emptyList() -) +private fun FunctionConstraint.toCallSignatures() = versions.map { + CallSignatureDeclaration( + parameters = it.parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, + type = it.returnConstraints.toType(), + typeParameters = emptyList() + ) +} private fun CallableConstraint.toCallSignature() = CallSignatureDeclaration( parameters = List(parameterCount) { NoTypeConstraint.toParameterDeclaration("") }, @@ -98,35 +104,30 @@ private fun CallableConstraint.toCallSignature() = CallSignatureDeclaration( typeParameters = emptyList() ) -private fun FunctionDeclaration.withStaticModifier(isStatic: Boolean) : FunctionDeclaration { - return this.copy(modifiers = if (isStatic) STATIC_MODIFIERS else emptyList()) -} +private fun FunctionConstraint.toMemberDeclarations(name: String, isStatic: Boolean) = + this.toDeclarations(name, if (isStatic) STATIC_MODIFIERS else emptyList()) -private fun FunctionConstraint.toMemberDeclaration(name: String, isStatic: Boolean) : MemberDeclaration? { - return this.toDeclaration(name, EXPORT_MODIFIERS).withStaticModifier(isStatic) -} - -private fun Constraint.toMemberDeclaration(name: String, isStatic: Boolean = false) : MemberDeclaration? { +private fun Constraint.toMemberDeclarations(name: String, isStatic: Boolean = false) : List { return when (this) { - is FunctionConstraint -> this.toMemberDeclaration(name, isStatic) - else -> getPropertyDeclaration(name, this.toType(), isStatic) + is FunctionConstraint -> this.toMemberDeclarations(name, isStatic) + else -> listOf(getPropertyDeclaration(name, this.toType(), isStatic)) } } -private fun ClassConstraint.toDeclaration(name: String, exportModifiers: List) : ClassDeclaration { +private fun ClassConstraint.toDeclaration(name: String, modifiers: List) : ClassDeclaration { val members = mutableListOf() val constructorConstraint = constructorConstraint if (constructorConstraint is FunctionConstraint) { - members.add(constructorConstraint.toConstructor()) + members.addAll(constructorConstraint.toConstructors()) } val prototype = this["prototype"] if (prototype is ObjectConstraint) { members.addAll( - prototype.propertyNames.mapNotNull { memberName -> - prototype[memberName]?.toMemberDeclaration(name = memberName, isStatic = false) + prototype.propertyNames.flatMap { memberName -> + prototype[memberName]?.toMemberDeclarations(name = memberName, isStatic = false) ?: emptyList() } ) } else { @@ -134,12 +135,12 @@ private fun ClassConstraint.toDeclaration(name: String, exportModifiers: List + propertyNames.flatMap { memberName -> //Don't output the prototype object if (memberName != "prototype") { - this[memberName]?.toMemberDeclaration(name = memberName, isStatic = true) + this[memberName]?.toMemberDeclarations(name = memberName, isStatic = true) ?: emptyList() } else { - null + emptyList() } } ) @@ -149,19 +150,23 @@ private fun ClassConstraint.toDeclaration(name: String, exportModifiers: List constraint.toParameterDeclaration(name) }, - type = returnConstraints.toType() +private fun FunctionConstraint.toType() : ParameterValueDeclaration { + return UnionTypeDeclaration( + params = versions.map { + FunctionTypeDeclaration( + parameters = it.parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, + type = it.returnConstraints.toType() + ) + } ) } -private fun UnionTypeConstraint.toType() : UnionTypeDeclaration { +private fun UnionTypeConstraint.toType() : ParameterValueDeclaration { return UnionTypeDeclaration( params = types.map { it.toType() } ) @@ -172,14 +177,14 @@ private fun ObjectConstraint.mapMembers() : List { callSignatureConstraints.forEach { when (it) { - is FunctionConstraint -> members.add(it.toCallSignature()) + is FunctionConstraint -> members.addAll(it.toCallSignatures()) is CallableConstraint -> members.add(it.toCallSignature()) } } members.addAll( - propertyNames.mapNotNull { memberName -> - this[memberName]?.toMemberDeclaration(name = memberName) + propertyNames.flatMap { memberName -> + this[memberName]?.toMemberDeclarations(name = memberName) ?: emptyList() } ) @@ -217,19 +222,21 @@ private fun Constraint.toType() : ParameterValueDeclaration { } } -private fun Constraint.toDeclaration(name: String, exportModifiers: List) : TopLevelDeclaration? { +private fun Constraint.toDeclarations(name: String, exportModifiers: List) : List { return when (this) { - is ClassConstraint -> this.toDeclaration(name, exportModifiers) - is FunctionConstraint -> this.toDeclaration(name, exportModifiers) - is CompositeConstraint -> raiseConcern("Unexpected composited type for variable named '$name'. Should be resolved by this point!") { null } - else -> getVariableDeclaration(name, this.toType(), exportModifiers) + is ClassConstraint -> listOf(this.toDeclaration(name, exportModifiers)) + is FunctionConstraint -> this.toDeclarations(name, exportModifiers) + is CompositeConstraint -> raiseConcern("Unexpected composited type for variable named '$name'. Should be resolved by this point!") { emptyList() } + else -> listOf(getVariableDeclaration(name, this.toType(), exportModifiers)) } } -fun Constraint.toDeclaration(name: String) = toDeclaration(name, EXPORT_MODIFIERS) +fun Constraint.toDeclarations(name: String) = toDeclarations(name, EXPORT_MODIFIERS) fun Constraint.asDefaultToDeclarations(defaultExportName: String) : List { - val declaration = this.toDeclaration(defaultExportName, DECLARE_MODIFIERS) + val declarations = this.toDeclarations(defaultExportName, DECLARE_MODIFIERS) + + val declaration = declarations.firstOrNull { it is WithUidDeclaration } return if (declaration is WithUidDeclaration) { val exportEqualsDeclaration = ExportAssignmentDeclaration( @@ -237,7 +244,9 @@ fun Constraint.asDefaultToDeclarations(defaultExportName: String) : List { - return environment.propertyNames.mapNotNull { propertyName -> + return environment.propertyNames.flatMap { propertyName -> val resolvedConstraint = environment[propertyName] - resolvedConstraint.toDeclaration(propertyName) + resolvedConstraint.toDeclarations(propertyName) } } } From fa7cd220d5c0c3aaafead76b8922337bb938295e Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Tue, 17 Dec 2019 16:09:19 +0100 Subject: [PATCH 139/172] Rename 'FunctionConstraint.Version' to 'FunctionConstraint.Overload' --- .../jetbrains/dukat/js/type/analysis/expression.kt | 5 ++--- .../type/constraint/composite/CompositeConstraint.kt | 4 ++-- .../type/constraint/properties/FunctionConstraint.kt | 12 ++++++------ .../reference/call/CallArgumentConstraint.kt | 6 +++--- .../reference/call/CallResultConstraint.kt | 6 +++--- .../constraint/resolution/constraintToDeclaration.kt | 8 ++++---- 6 files changed, 20 insertions(+), 21 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 1fd1e44a9..6c24211f0 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -4,7 +4,6 @@ import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.reference.ReferenceConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint -import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.CallableConstraint import org.jetbrains.dukat.js.type.property_owner.PropertyOwner import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConstraint @@ -43,7 +42,7 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) : FunctionConstraint? { return if (this.body != null) { val pathWalker = PathWalker() - val versions = mutableListOf() + val versions = mutableListOf() do { val functionScope = Scope(owner) @@ -58,7 +57,7 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) : FunctionConstraint? { val returnTypeConstraints = body!!.calculateConstraints(functionScope, pathWalker) ?: VoidTypeConstraint - versions.add(FunctionConstraint.Version( + versions.add(FunctionConstraint.Overload( returnConstraints = returnTypeConstraints, parameterConstraints = parameterConstraints )) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt index bf3421fe7..56cf95d0e 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt @@ -78,8 +78,8 @@ class CompositeConstraint( val resultConstraint: PropertyOwnerConstraint = if (callableConstraints.isNotEmpty() && callsCanBeUnified) { FunctionConstraint( owner = owner, - versions = callableConstraints.map { callable -> - FunctionConstraint.Version( + overloads = callableConstraints.map { callable -> + FunctionConstraint.Overload( callable.returnConstraints, List(parameterCount) { i -> "`$i`" to NoTypeConstraint } ) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt index 1b90e4eb0..d8ef48e8d 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt @@ -8,10 +8,10 @@ import org.jetbrains.dukat.js.type.property_owner.PropertyOwner class FunctionConstraint( owner: PropertyOwner, - val versions: List + val overloads: List ) : PropertyOwnerConstraint(owner) { - data class Version( + data class Overload( val returnConstraints: Constraint, val parameterConstraints: List> ) @@ -33,7 +33,7 @@ class FunctionConstraint( private fun getParameterNames() : List { val parameters = mutableListOf() - versions.forEach { + overloads.forEach { it.parameterConstraints.forEachIndexed { index, (name, _) -> if (parameters.size <= index) { parameters.add(index, name) @@ -80,8 +80,8 @@ class FunctionConstraint( private fun getResolvedCallable() = FunctionConstraint( owner, - versions.map { - Version( + overloads.map { + Overload( it.returnConstraints.resolve(), it.parameterConstraints.map { (name, constraint) -> name to constraint.resolve(resolveAsInput = true) } ) @@ -124,7 +124,7 @@ class FunctionConstraint( ResolutionState.RESOLVING -> { FunctionConstraint( owner, - listOf(Version( + listOf(Overload( returnConstraints = RecursiveConstraint, parameterConstraints = getParameterNames().map { it to NoTypeConstraint } )) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt index 85f24c554..551200134 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt @@ -16,15 +16,15 @@ class CallArgumentConstraint( val functionConstraint = callTarget.resolve() if (functionConstraint is FunctionConstraint) { - if (functionConstraint.versions.size == 1) { - val parameters = functionConstraint.versions[0].parameterConstraints + if (functionConstraint.overloads.size == 1) { + val parameters = functionConstraint.overloads[0].parameterConstraints if (parameters.size > argumentNum) { return parameters[argumentNum].second.resolve(resolveAsInput = true) } } else { return UnionTypeConstraint( - functionConstraint.versions.mapNotNull { + functionConstraint.overloads.mapNotNull { if (it.parameterConstraints.size > argumentNum) { it.parameterConstraints[argumentNum].second.resolve(resolveAsInput = true) } else null diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt index 7b0107427..359dcf680 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt @@ -15,11 +15,11 @@ class CallResultConstraint( val functionConstraint = callTarget.resolve() return if (functionConstraint is FunctionConstraint) { - if (functionConstraint.versions.size == 1) { - functionConstraint.versions[0].returnConstraints.resolveWithProperties() + if (functionConstraint.overloads.size == 1) { + functionConstraint.overloads[0].returnConstraints.resolveWithProperties() } else { UnionTypeConstraint( - functionConstraint.versions.map { + functionConstraint.overloads.map { it.returnConstraints.resolveWithProperties() } ).resolve() diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index 4ad41a7ef..aca1587b6 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -69,7 +69,7 @@ private fun Constraint.toParameterDeclaration(name: String) = ParameterDeclarati optional = false ) -private fun FunctionConstraint.toDeclarations(name: String, modifiers: List) = versions.map { +private fun FunctionConstraint.toDeclarations(name: String, modifiers: List) = overloads.map { FunctionDeclaration( name = name, parameters = it.parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, @@ -81,7 +81,7 @@ private fun FunctionConstraint.toDeclarations(name: String, modifiers: List constraint.toParameterDeclaration(name) }, typeParameters = emptyList(), @@ -90,7 +90,7 @@ private fun FunctionConstraint.toConstructors() = versions.map { ) } -private fun FunctionConstraint.toCallSignatures() = versions.map { +private fun FunctionConstraint.toCallSignatures() = overloads.map { CallSignatureDeclaration( parameters = it.parameterConstraints.map { (name, constraint) -> constraint.toParameterDeclaration(name) }, type = it.returnConstraints.toType(), @@ -157,7 +157,7 @@ private fun ClassConstraint.toDeclaration(name: String, modifiers: List constraint.toParameterDeclaration(name) }, type = it.returnConstraints.toType() From fb70b1b9dc3d6a5a711f1775f17b8a4eeffbbfef Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Fri, 27 Dec 2019 16:18:23 +0100 Subject: [PATCH 140/172] Track function overloads seperately, if valid. --- .../arguments/callResultModified.d.kt | 4 +- .../arguments/optionalProperties.d.kt | 4 +- .../javascript/class/memberModification.d.kt | 14 +- .../test/data/javascript/conditional/if.d.kt | 4 +- .../javascript/function/asDifferentTypes.d.kt | 2 +- .../data/javascript/instance/instance.d.kt | 10 +- .../data/javascript/object/construct.d.kt | 2 +- .../data/javascript/reference/property.d.kt | 6 +- .../data/javascript/throw/onCondition.d.kt | 2 +- .../dukat/js/translator/JavaScriptLowerer.kt | 2 +- .../dukat/js/type/analysis/members.kt | 2 +- .../resolution/constraintToDeclaration.kt | 22 +- .../dukat/tsLowerings/mergeDuplicates.kt | 138 ------------ .../tsLowerings/mergeDuplicates/getNewUID.kt | 7 + .../mergeDuplicates/mergeDuplicates.kt | 209 ++++++++++++++++++ .../mergeDuplicates/reintroduceUIDs.kt | 55 +++++ .../mergeDuplicates/removeUnneeded.kt | 72 ++++++ .../nodeLowering/lowerings/introduceModels.kt | 16 +- 18 files changed, 383 insertions(+), 188 deletions(-) delete mode 100644 typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates.kt create mode 100644 typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt create mode 100644 typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt create mode 100644 typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/reintroduceUIDs.kt create mode 100644 typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt diff --git a/compiler/test/data/javascript/arguments/callResultModified.d.kt b/compiler/test/data/javascript/arguments/callResultModified.d.kt index 430cb0b29..977e0cae1 100644 --- a/compiler/test/data/javascript/arguments/callResultModified.d.kt +++ b/compiler/test/data/javascript/arguments/callResultModified.d.kt @@ -30,4 +30,6 @@ external interface `T$1` { set(value) = definedExternally } -external fun generateVector(vectorProvider: (`0`: Any? /* = null */, `1`: Any? /* = null */, `2`: Any? /* = null */) -> dynamic): `T$1` \ No newline at end of file +external fun generateVector(vectorProvider: (`0`: Any? /* = null */, `1`: Any? /* = null */, `2`: Any? /* = null */) -> `T$0`): `T$1` + +external fun generateVector(vectorProvider: (`0`: Any? /* = null */, `1`: Any? /* = null */, `2`: Any? /* = null */) -> Any?): `T$1` \ No newline at end of file diff --git a/compiler/test/data/javascript/arguments/optionalProperties.d.kt b/compiler/test/data/javascript/arguments/optionalProperties.d.kt index b1d927492..1c7743dc4 100644 --- a/compiler/test/data/javascript/arguments/optionalProperties.d.kt +++ b/compiler/test/data/javascript/arguments/optionalProperties.d.kt @@ -21,11 +21,11 @@ external interface `T$0` { var z: Number } +external fun lengthOf(vector: `T$0`): Any? + external interface `T$1` { var x: Number var y: Number } -external fun lengthOf(vector: `T$0`): Any? - external fun lengthOf(vector: `T$1`): Any? \ No newline at end of file diff --git a/compiler/test/data/javascript/class/memberModification.d.kt b/compiler/test/data/javascript/class/memberModification.d.kt index 9a0a3ee5f..c2bc8fcd3 100644 --- a/compiler/test/data/javascript/class/memberModification.d.kt +++ b/compiler/test/data/javascript/class/memberModification.d.kt @@ -15,16 +15,16 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* +external var falseStr: Number + +external var trueNum: Number + +external var falseBool: Number + external open class ModifiedLiterals { companion object { fun getStringLiteral(): Number fun getNumberLiteral(): Number fun getBooleanLiteral(): Number } -} - -external var falseStr: Number - -external var trueNum: Number - -external var falseBool: Number \ No newline at end of file +} \ No newline at end of file diff --git a/compiler/test/data/javascript/conditional/if.d.kt b/compiler/test/data/javascript/conditional/if.d.kt index a8f815dda..48e4342c3 100644 --- a/compiler/test/data/javascript/conditional/if.d.kt +++ b/compiler/test/data/javascript/conditional/if.d.kt @@ -17,6 +17,6 @@ import org.w3c.xhr.* external fun max(a: Number, b: Number): Number -external fun negate(a: Number): dynamic /* Number | Boolean */ +external fun negate(a: Number): Number -external fun negate(a: Any?): dynamic /* Number | Boolean */ \ No newline at end of file +external fun negate(a: Any?): Boolean \ No newline at end of file diff --git a/compiler/test/data/javascript/function/asDifferentTypes.d.kt b/compiler/test/data/javascript/function/asDifferentTypes.d.kt index b72d503e4..f42456c4c 100644 --- a/compiler/test/data/javascript/function/asDifferentTypes.d.kt +++ b/compiler/test/data/javascript/function/asDifferentTypes.d.kt @@ -15,4 +15,4 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun getOperation(operator: Any?): (Number, Number) -> Number \ No newline at end of file +external fun getOperation(operator: Any?): dynamic /* (Number, Number) -> Number | Nothing */ \ No newline at end of file diff --git a/compiler/test/data/javascript/instance/instance.d.kt b/compiler/test/data/javascript/instance/instance.d.kt index e38603e9c..2c41391f0 100644 --- a/compiler/test/data/javascript/instance/instance.d.kt +++ b/compiler/test/data/javascript/instance/instance.d.kt @@ -15,12 +15,12 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external open class C { - open fun foo(): String -} - external object o { fun foo(): String } -external var str: String \ No newline at end of file +external var str: String + +external open class C { + open fun foo(): String +} \ No newline at end of file diff --git a/compiler/test/data/javascript/object/construct.d.kt b/compiler/test/data/javascript/object/construct.d.kt index 87cd79098..2d5fc2abc 100644 --- a/compiler/test/data/javascript/object/construct.d.kt +++ b/compiler/test/data/javascript/object/construct.d.kt @@ -25,6 +25,6 @@ external object v { var x: Number var y: Number var z: Number - fun negate(x: Any?, y: Any?, z: Any?): `T$0` var double: `T$0` + fun negate(x: Any?, y: Any?, z: Any?): `T$0` } \ No newline at end of file diff --git a/compiler/test/data/javascript/reference/property.d.kt b/compiler/test/data/javascript/reference/property.d.kt index 18354a35a..a1bf4c4ef 100644 --- a/compiler/test/data/javascript/reference/property.d.kt +++ b/compiler/test/data/javascript/reference/property.d.kt @@ -15,10 +15,10 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* +external fun wrapperFun(): String + external open class PropertyOwner { companion object { fun property(): String } -} - -external fun wrapperFun(): String \ No newline at end of file +} \ No newline at end of file diff --git a/compiler/test/data/javascript/throw/onCondition.d.kt b/compiler/test/data/javascript/throw/onCondition.d.kt index ff557d67b..42889b7e1 100644 --- a/compiler/test/data/javascript/throw/onCondition.d.kt +++ b/compiler/test/data/javascript/throw/onCondition.d.kt @@ -15,4 +15,4 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun assertNotNull(value: Any?, message: Any?): Any? \ No newline at end of file +external fun assertNotNull(value: Any?, message: Any?): dynamic /* Nothing | Any? */ \ No newline at end of file diff --git a/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt b/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt index 0b76f2444..404d5ba92 100644 --- a/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt +++ b/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt @@ -5,7 +5,7 @@ import org.jetbrains.dukat.astModel.SourceSetModel import org.jetbrains.dukat.js.type.analysis.introduceTypes import org.jetbrains.dukat.moduleNameResolver.ModuleNameResolver import org.jetbrains.dukat.ts.translator.TypescriptLowerer -import org.jetbrains.dukat.tsLowerings.mergeDuplicates +import org.jetbrains.dukat.tsLowerings.mergeDuplicates.mergeDuplicates import org.jetbrains.dukat.tsmodel.SourceSetDeclaration import org.jetrbains.dukat.nodeLowering.lowerings.FqNode diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt index 2f7f8e4fa..db2c848d5 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt @@ -23,7 +23,7 @@ fun ConstructorDeclaration.addTo(owner: ClassConstraint) { typeParameters = typeParameters, modifiers = modifiers, body = body, - uid = "__NO_UID__" + uid = "" ).addTo(owner) } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index aca1587b6..4096bc5fa 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -202,8 +202,7 @@ private fun ObjectConstraint.mapMembers() : List { private fun ObjectConstraint.toType() : ObjectLiteralDeclaration { return ObjectLiteralDeclaration( members = mapMembers(), - uid = getUID(), - nullable = true + uid = getUID() ) } @@ -234,21 +233,14 @@ private fun Constraint.toDeclarations(name: String, exportModifiers: List { - val declarations = this.toDeclarations(defaultExportName, DECLARE_MODIFIERS) - - val declaration = declarations.firstOrNull { it is WithUidDeclaration } + val declarations = this.toDeclarations(defaultExportName, DECLARE_MODIFIERS).toMutableList() - return if (declaration is WithUidDeclaration) { - val exportEqualsDeclaration = ExportAssignmentDeclaration( - declaration.uid, - true - ) + val uidOwner = declarations.firstOrNull { it is WithUidDeclaration } - declarations.toMutableList().apply { - add(exportEqualsDeclaration) - } - } else { - emptyList() + if (uidOwner is WithUidDeclaration) { + declarations.add(ExportAssignmentDeclaration(uidOwner.uid, true)) } + + return declarations } diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates.kt deleted file mode 100644 index 8e74087d0..000000000 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates.kt +++ /dev/null @@ -1,138 +0,0 @@ -package org.jetbrains.dukat.tsLowerings - -import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration -import org.jetbrains.dukat.tsmodel.ClassDeclaration -import org.jetbrains.dukat.tsmodel.ConstructorDeclaration -import org.jetbrains.dukat.tsmodel.FunctionDeclaration -import org.jetbrains.dukat.tsmodel.MemberDeclaration -import org.jetbrains.dukat.tsmodel.ModuleDeclaration -import org.jetbrains.dukat.tsmodel.ParameterDeclaration -import org.jetbrains.dukat.tsmodel.SourceFileDeclaration -import org.jetbrains.dukat.tsmodel.SourceSetDeclaration -import org.jetbrains.dukat.tsmodel.TopLevelDeclaration -import org.jetbrains.dukat.tsmodel.VariableDeclaration -import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration -import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration -import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration -import org.jetbrains.dukat.tsmodel.types.TypeDeclaration -import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration - -private fun FunctionTypeDeclaration.removeParameterNames() = copy( - parameters = parameters.map { it.copy(name = "") } -) - -private fun List.mergeFunctionTypes() : List { - val fixedFunctions = map { it.mergeDuplicates() } - - val groups = fixedFunctions.groupBy { it.removeParameterNames() } - - return groups.map { (combination, functions) -> - if (functions.size == 1) { - functions[0] - } else { - //TODO check if the names are all the same, in which case removing them isn't necessary - combination - } - } -} - -private fun List.mergeObjectTypes() : List { - return toSet().toList() //TODO check if this is enough -} - -private fun List.mergeTypeDeclarations() : List { - return toSet().toList() -} - -private fun UnionTypeDeclaration.mergeUnion() : ParameterValueDeclaration { - val types = mutableListOf() - val functionTypes = mutableListOf() - val objectTypes = mutableListOf() - val typeDeclarations = mutableListOf() - - params.forEach { - when (it) { - is FunctionTypeDeclaration -> functionTypes += it - is ObjectLiteralDeclaration -> objectTypes += it - is TypeDeclaration -> typeDeclarations += it - else -> types += it.mergeDuplicates() - } - } - - types.addAll(functionTypes.mergeFunctionTypes()) - types.addAll(objectTypes.mergeObjectTypes()) - types.addAll(typeDeclarations.mergeTypeDeclarations()) - - return when (types.size) { - 1 -> types[0] - else -> UnionTypeDeclaration(types) - } -} - -private fun ParameterValueDeclaration.mergeDuplicates() : ParameterValueDeclaration { - return when (this) { - is FunctionTypeDeclaration -> this.mergeDuplicates() - is UnionTypeDeclaration -> this.mergeUnion() - else -> this - } -} - -private fun ParameterDeclaration.mergeDuplicates() = copy( - type = type.mergeDuplicates() -) - -private fun ConstructorDeclaration.mergeDuplicates() = copy( - parameters = parameters.map { it.mergeDuplicates() } -) - -private fun CallSignatureDeclaration.mergeDuplicates() = copy( - parameters = parameters.map { it.mergeDuplicates() } -) - -private fun MemberDeclaration.mergeDuplicates() : MemberDeclaration { - return when (this) { - is ConstructorDeclaration -> this.mergeDuplicates() - is FunctionDeclaration -> this.mergeDuplicates() - is CallSignatureDeclaration -> this.mergeDuplicates() - else -> this - } -} - -private fun ClassDeclaration.mergeDuplicates() = copy( - members = members.map { it.mergeDuplicates() } -) - -private fun FunctionTypeDeclaration.mergeDuplicates() = copy( - parameters = parameters.map { it.mergeDuplicates() }, - type = type.mergeDuplicates() -) - -private fun FunctionDeclaration.mergeDuplicates() = copy( - parameters = parameters.map { it.mergeDuplicates() }, - type = type.mergeDuplicates() -) - -private fun VariableDeclaration.mergeDuplicates() = copy( - type = type.mergeDuplicates() -) - -private fun TopLevelDeclaration.mergeDuplicates() : TopLevelDeclaration { - return when (this) { - is ClassDeclaration -> this.mergeDuplicates() - is FunctionDeclaration -> this.mergeDuplicates() - is VariableDeclaration -> this.mergeDuplicates() - else -> this - } -} - -fun ModuleDeclaration.mergeDuplicates() = copy( - declarations = declarations.map { it.mergeDuplicates() } -) - -fun SourceFileDeclaration.mergeDuplicates() = copy( - root = root.mergeDuplicates() -) - -fun SourceSetDeclaration.mergeDuplicates() = copy( - sources = sources.map { it.mergeDuplicates() } -) \ No newline at end of file diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt new file mode 100644 index 000000000..fe5a0d393 --- /dev/null +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.tsLowerings.mergeDuplicates + +private var uid = 0; + +internal fun getNewUID() : String { + return "reintroduced_uid_${uid++}" +} \ No newline at end of file diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt new file mode 100644 index 000000000..d2eb46d44 --- /dev/null +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -0,0 +1,209 @@ +package org.jetbrains.dukat.tsLowerings.mergeDuplicates + +import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration +import org.jetbrains.dukat.tsmodel.ClassDeclaration +import org.jetbrains.dukat.tsmodel.ConstructorDeclaration +import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.MemberDeclaration +import org.jetbrains.dukat.tsmodel.ModuleDeclaration +import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.SourceFileDeclaration +import org.jetbrains.dukat.tsmodel.SourceSetDeclaration +import org.jetbrains.dukat.tsmodel.TopLevelDeclaration +import org.jetbrains.dukat.tsmodel.VariableDeclaration +import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration +import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration +import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration +import org.jetbrains.dukat.tsmodel.types.TypeDeclaration +import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration + +private fun List.mergeFunctionTypes() : List { + val minimizedFunctions = map { it.mergeDuplicates() } + + val groups = minimizedFunctions.groupBy { it.removeUnneeded() } + + return groups.map { (combination, functions) -> + if (functions.size == 1) { + functions[0] + } else { + combination + } + } +} + +private fun List.mergeObjectTypes() : List { + return map { it.mergeDuplicates() }.distinct() +} + +private fun List.mergeTypeDeclarations() : List { + return distinct() +} + +private fun UnionTypeDeclaration.mergeUnion() : ParameterValueDeclaration { + val types = mutableListOf() + val functionTypes = mutableListOf() + val objectTypes = mutableListOf() + val typeDeclarations = mutableListOf() + + params.forEach { + when (it) { + is FunctionTypeDeclaration -> functionTypes += it + is ObjectLiteralDeclaration -> objectTypes += it + is TypeDeclaration -> typeDeclarations += it + else -> types += it.mergeDuplicates() + } + } + + types.addAll(functionTypes.mergeFunctionTypes()) + types.addAll(objectTypes.mergeObjectTypes()) + types.addAll(typeDeclarations.mergeTypeDeclarations()) + + return when (types.size) { + 1 -> types[0] + else -> UnionTypeDeclaration(types) + } +} + +private fun ParameterValueDeclaration.mergeDuplicates() : ParameterValueDeclaration { + return when (this) { + is FunctionTypeDeclaration -> this.mergeDuplicates() + is ObjectLiteralDeclaration -> this.mergeDuplicates() + is UnionTypeDeclaration -> this.mergeUnion() + else -> this + } +} + +private fun FunctionDeclaration.addReturnTypeFrom(originals: List) = copy( + type = UnionTypeDeclaration(originals.map { it.type }).mergeUnion() +) + +private fun List.mergeFunctions() : List { + val fixedFunctions = map { it.mergeDuplicates() } + + val groups = fixedFunctions.groupBy { it.removeUnneededAndReturnType() } + + return groups.map { (functionStub, functions) -> + if (functions.size == 1) { + functions[0] + } else { + functionStub.addReturnTypeFrom(functions).reintroduceUIDsFromSource(functions[0]) + } + } +} + +private fun CallSignatureDeclaration.addReturnTypeFrom(originals: List) = copy( + type = UnionTypeDeclaration(originals.map { it.type }).mergeUnion() +) + +private fun List.mergeCallSignatures() : List { + val fixedCallSignatures = map { it.mergeDuplicates() } + + val groups = fixedCallSignatures.groupBy { it.removeUnneededAndReturnType() } + + return groups.map { (callSignatureStub, callSignatures) -> + if (callSignatures.size == 1) { + callSignatures[0] + } else { + callSignatureStub.addReturnTypeFrom(callSignatures).reintroduceUIDs() + } + } +} + +private fun List.mergeMembers() : List { + val otherMembers = mutableListOf() + val constructors = mutableListOf() + val methods = mutableListOf() + val callSignatures = mutableListOf() + + forEach { member -> + when (member) { + is ConstructorDeclaration -> constructors += member.mergeDuplicates() + is FunctionDeclaration -> methods += member.mergeDuplicates() + is CallSignatureDeclaration -> callSignatures += member.mergeDuplicates() + else -> otherMembers += member + } + } + + val members = mutableListOf() + + members.addAll(constructors.distinct()) + members.addAll(callSignatures.mergeCallSignatures()) + members.addAll(otherMembers) + members.addAll(methods.mergeFunctions()) + + return members +} + +private fun ParameterDeclaration.mergeDuplicates() = copy( + type = type.mergeDuplicates() +) + +private fun ConstructorDeclaration.mergeDuplicates() = copy( + parameters = parameters.map { it.mergeDuplicates() } +) + +private fun CallSignatureDeclaration.mergeDuplicates() = copy( + parameters = parameters.map { it.mergeDuplicates() } +) + +private fun ClassDeclaration.mergeDuplicates() = copy( + members = members.mergeMembers() +) + +private fun ObjectLiteralDeclaration.mergeDuplicates() = copy( + members = members.mergeMembers() +) + +private fun FunctionTypeDeclaration.mergeDuplicates() = copy( + parameters = parameters.map { it.mergeDuplicates() }, + type = type.mergeDuplicates() +) + +private fun FunctionDeclaration.mergeDuplicates() = copy( + parameters = parameters.map { it.mergeDuplicates() }, + type = type.mergeDuplicates() +) + +private fun VariableDeclaration.mergeDuplicates() = copy( + type = type.mergeDuplicates() +) + +private fun List.mergeTopLevelDeclarations() : List { + val otherDeclarations = mutableListOf() + val classes = mutableListOf() + val functions = mutableListOf() + val variables = mutableListOf() + + forEach { declaration -> + when (declaration) { + is ClassDeclaration -> classes += declaration.mergeDuplicates() + is FunctionDeclaration -> functions += declaration.mergeDuplicates() + is VariableDeclaration -> variables += declaration.mergeDuplicates() + else -> otherDeclarations += declaration + } + } + + val declarations = mutableListOf() + + declarations.addAll(variables.distinct()) + declarations.addAll(functions.mergeFunctions()) + declarations.addAll(classes.distinct()) + declarations.addAll(otherDeclarations) + + return declarations +} + +fun ModuleDeclaration.mergeDuplicates() = copy( + declarations = declarations.mergeTopLevelDeclarations() +) + +fun SourceFileDeclaration.mergeDuplicates() = copy( + root = root.mergeDuplicates() +) + +fun SourceSetDeclaration.mergeDuplicates() : SourceSetDeclaration { + val mergedSources = sources.map { it.mergeDuplicates() } + return copy( + sources = mergedSources + ) +} \ No newline at end of file diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/reintroduceUIDs.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/reintroduceUIDs.kt new file mode 100644 index 000000000..48d68d95c --- /dev/null +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/reintroduceUIDs.kt @@ -0,0 +1,55 @@ +package org.jetbrains.dukat.tsLowerings.mergeDuplicates + +import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.MemberDeclaration +import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration +import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration +import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration +import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration + +private fun ParameterDeclaration.reintroduceUIDs() = copy( + type = type.reintroduceUIDs() +) + +private fun FunctionTypeDeclaration.reintroduceUIDs() = copy( + type = type.reintroduceUIDs(), + parameters = parameters.map { it.reintroduceUIDs() } +) + +private fun ObjectLiteralDeclaration.reintroduceUIDs() = copy( + members = members.map { it.reintroduceUIDs() }, + uid = getNewUID() +) + +private fun FunctionDeclaration.reintroduceUIDs() = copy( + type = type.reintroduceUIDs(), + parameters = parameters.map { it.reintroduceUIDs() }, + uid = getNewUID() +) + +private fun UnionTypeDeclaration.reintroduceUIDs() = copy( + params = params.map { it.reintroduceUIDs() } +) + +@Suppress("UNCHECKED_CAST") +internal fun T.reintroduceUIDs(): T { + return when (this) { + is FunctionDeclaration -> this.reintroduceUIDs() as T + is ObjectLiteralDeclaration -> this.reintroduceUIDs() as T + else -> this + } +} + +internal fun ParameterValueDeclaration.reintroduceUIDs(): ParameterValueDeclaration { + return when (this) { + is FunctionTypeDeclaration -> this.reintroduceUIDs() + is ObjectLiteralDeclaration -> this.reintroduceUIDs() + is UnionTypeDeclaration -> this.reintroduceUIDs() + else -> this + } +} + +internal fun FunctionDeclaration.reintroduceUIDsFromSource(source: FunctionDeclaration) = reintroduceUIDs().copy( + uid = source.uid +) \ No newline at end of file diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt new file mode 100644 index 000000000..73205fb80 --- /dev/null +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt @@ -0,0 +1,72 @@ +package org.jetbrains.dukat.tsLowerings.mergeDuplicates + +import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration +import org.jetbrains.dukat.tsmodel.ConstructorDeclaration +import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.MemberDeclaration +import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration +import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration +import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration +import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration + +internal fun ParameterDeclaration.removeUnneeded(name: String = "") = copy( + name = name, + type = type.removeUnneeded() +) + +internal fun CallSignatureDeclaration.removeUnneededAndReturnType() = removeUnneeded().copy( + type = UnionTypeDeclaration(emptyList()) //Dummy (invalid type) +) + +internal fun CallSignatureDeclaration.removeUnneeded() = copy( + parameters = parameters.map { parameter -> parameter.removeUnneeded(parameter.name) }, + type = type.removeUnneeded() +) + +internal fun ConstructorDeclaration.removeUnneeded() = copy( + parameters = parameters.map { it.removeUnneeded() } +) + +internal fun MemberDeclaration.removeUnneeded() : MemberDeclaration { + return when (this) { + is CallSignatureDeclaration -> this.removeUnneeded() + is ConstructorDeclaration -> this.removeUnneeded() + is FunctionDeclaration -> this.removeUnneeded() + else -> this + } +} + +internal fun FunctionTypeDeclaration.removeUnneeded() = copy( + parameters = parameters.map { it.removeUnneeded() }, + type = type.removeUnneeded() +) + +internal fun FunctionDeclaration.removeUnneededAndReturnType() = removeUnneeded().copy( + type = UnionTypeDeclaration(emptyList()) //Dummy (invalid type) +) + +internal fun FunctionDeclaration.removeUnneeded() = copy( + parameters = parameters.map { parameter -> parameter.removeUnneeded(parameter.name) }, + type = type.removeUnneeded(), + body = null, + uid = "" +) + +internal fun UnionTypeDeclaration.removeUnneeded() = copy( + params = params.map { it.removeUnneeded() } +) + +internal fun ObjectLiteralDeclaration.removeUnneeded() = copy( + members = members.map { it.removeUnneeded() }, + uid = "" +) + +internal fun ParameterValueDeclaration.removeUnneeded() : ParameterValueDeclaration { + return when (this) { + is FunctionTypeDeclaration -> this.removeUnneeded() + is ObjectLiteralDeclaration -> this.removeUnneeded() + is UnionTypeDeclaration -> this.removeUnneeded() + else -> this + } +} diff --git a/typescript/ts-node-lowering/src/org/jetrbains/dukat/nodeLowering/lowerings/introduceModels.kt b/typescript/ts-node-lowering/src/org/jetrbains/dukat/nodeLowering/lowerings/introduceModels.kt index 3aa0352f2..e846dc0d7 100644 --- a/typescript/ts-node-lowering/src/org/jetrbains/dukat/nodeLowering/lowerings/introduceModels.kt +++ b/typescript/ts-node-lowering/src/org/jetrbains/dukat/nodeLowering/lowerings/introduceModels.kt @@ -274,16 +274,12 @@ private class NodeConverter(private val uidToNameMapper: UidMapper) { stringEntity.addLibPrefix() ) } else { - if (params.size == 1) { - params[0].process(context) - } else { - TypeValueModel( - dynamicName, - emptyList(), - convertMeta(), - null - ) - } + TypeValueModel( + dynamicName, + emptyList(), + convertMeta(), + null + ) } is TupleTypeNode -> TypeValueModel( dynamicName, From 08388c457982ee5a8a8af08c10cd64af47a573c7 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Fri, 27 Dec 2019 16:47:14 +0100 Subject: [PATCH 141/172] Fix duplicate UIDs in call-signature overloads --- .../mergeDuplicates/reintroduceUIDs.kt | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/reintroduceUIDs.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/reintroduceUIDs.kt index 48d68d95c..5c444dab0 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/reintroduceUIDs.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/reintroduceUIDs.kt @@ -1,8 +1,10 @@ package org.jetbrains.dukat.tsLowerings.mergeDuplicates +import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.MemberDeclaration import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration @@ -28,15 +30,20 @@ private fun FunctionDeclaration.reintroduceUIDs() = copy( uid = getNewUID() ) +internal fun CallSignatureDeclaration.reintroduceUIDs() = copy( + type = type.reintroduceUIDs(), + parameters = parameters.map { it.reintroduceUIDs() } +) + private fun UnionTypeDeclaration.reintroduceUIDs() = copy( params = params.map { it.reintroduceUIDs() } ) -@Suppress("UNCHECKED_CAST") -internal fun T.reintroduceUIDs(): T { +internal fun MemberDeclaration.reintroduceUIDs(): MemberDeclaration { return when (this) { - is FunctionDeclaration -> this.reintroduceUIDs() as T - is ObjectLiteralDeclaration -> this.reintroduceUIDs() as T + is FunctionDeclaration -> this.reintroduceUIDs() + is ObjectLiteralDeclaration -> this.reintroduceUIDs() + is CallSignatureDeclaration -> this.reintroduceUIDs() else -> this } } From f1f6cc1e522558f7ad6cfed848ea1857463a14e0 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Mon, 30 Dec 2019 10:26:53 +0100 Subject: [PATCH 142/172] Remove outdated TODO --- .../dukat/js/type/constraint/properties/ObjectConstraint.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt index 3b938ddb2..ea4c81f80 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt @@ -32,7 +32,7 @@ class ObjectConstraint( raiseConcern("Instantiating constraint which cannot be instantiated!") { null } } } else { - null //TODO make sure an unresolved class being instantiated works + null } } } From e09658c9d2a29ae31eb3eff3cafa2727d2385599 Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Mon, 30 Dec 2019 16:30:33 +0100 Subject: [PATCH 143/172] Removed unused import --- .../src/org/jetbrains/dukat/compiler/tests/core/JSTypeTests.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/JSTypeTests.kt b/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/JSTypeTests.kt index b483376ed..5ddffc93e 100644 --- a/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/JSTypeTests.kt +++ b/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/JSTypeTests.kt @@ -1,6 +1,5 @@ package org.jetbrains.dukat.compiler.tests.core -import org.jetbrains.dukat.panic.setPanicMode import org.jetbrains.dukat.compiler.tests.BundleTranslator import org.jetbrains.dukat.compiler.tests.FileFetcher import org.jetbrains.dukat.compiler.tests.OutputTests @@ -10,7 +9,7 @@ import org.jetbrains.dukat.compiler.tests.core.TestConfig.NODE_PATH import org.jetbrains.dukat.js.translator.JavaScriptLowerer import org.jetbrains.dukat.moduleNameResolver.ConstNameResolver import org.jetbrains.dukat.panic.PanicMode -import org.jetbrains.dukat.panic.resolvePanicMode +import org.jetbrains.dukat.panic.setPanicMode import org.jetbrains.dukat.translator.InputTranslator import org.jetbrains.dukat.translatorString.TS_DECLARATION_EXTENSION import org.jetbrains.dukat.translatorString.translateModule From d14188dbb49b28adc28e95aee79e2a6fbb7319e0 Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Tue, 31 Dec 2019 12:50:09 +0100 Subject: [PATCH 144/172] Make links navigatable in CoreSetCliTests and CoreSetTests Also, today I've learnt that there's no such word - "navigatable" in English. --- .../org/jetbrains/dukat/compiler/tests/core/CoreSetCliTests.kt | 3 ++- .../org/jetbrains/dukat/compiler/tests/core/CoreSetTests.kt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/CoreSetCliTests.kt b/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/CoreSetCliTests.kt index 1c44c248b..82681db45 100644 --- a/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/CoreSetCliTests.kt +++ b/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/CoreSetCliTests.kt @@ -9,6 +9,7 @@ import org.jetbrains.dukat.compiler.tests.OutputTests import org.jetbrains.dukat.compiler.tests.createStandardCliTranslator import org.jetbrains.dukat.compiler.tests.extended.CliTestsEnded import org.jetbrains.dukat.compiler.tests.extended.CliTestsStarted +import org.jetbrains.dukat.compiler.tests.toFileUriScheme import org.jetbrains.dukat.panic.resolvePanicMode import org.jetbrains.dukat.translatorString.TS_DECLARATION_EXTENSION import org.junit.jupiter.api.DisplayName @@ -56,7 +57,7 @@ class CoreSetCliTests { tsPath: String, ktPath: String ) { - print("\nSOURCE:\tfile:///${tsPath}\nTARGET:\tfile:///${ktPath}\n") + print("\nSOURCE:\t${tsPath.toFileUriScheme()}\nTARGET:\t${ktPath.toFileUriScheme()}") val reportPath = "./build/reports/core/cli/${descriptor}.json" val dirName = "./build/tests/core/cli/${descriptor}" diff --git a/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/CoreSetTests.kt b/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/CoreSetTests.kt index c8358ba87..b87911191 100644 --- a/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/CoreSetTests.kt +++ b/compiler/test/src/org/jetbrains/dukat/compiler/tests/core/CoreSetTests.kt @@ -6,6 +6,7 @@ import org.jetbrains.dukat.compiler.tests.OutputTests import org.jetbrains.dukat.compiler.tests.core.TestConfig.CONVERTER_SOURCE_PATH import org.jetbrains.dukat.compiler.tests.core.TestConfig.DEFAULT_LIB_PATH import org.jetbrains.dukat.compiler.tests.core.TestConfig.NODE_PATH +import org.jetbrains.dukat.compiler.tests.toFileUriScheme import org.jetbrains.dukat.moduleNameResolver.ConstNameResolver import org.jetbrains.dukat.moduleNameResolver.ModuleNameResolver import org.jetbrains.dukat.translator.InputTranslator @@ -57,7 +58,7 @@ class CoreSetTests : OutputTests() { val modules = translateModule(bundle.translate(tsPath)) val translated = concatenate(tsPath, modules) - print("\nSOURCE:\tfile:///${tsPath}\nTARGET:\tfile:///${ktPath}") + print("\nSOURCE:\t${tsPath.toFileUriScheme()}\nTARGET:\t${ktPath.toFileUriScheme()}") assertEquals( translated, From 8e462008d89e04d49a0839f9b42c87ca9e55f3ed Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 13:03:57 +0100 Subject: [PATCH 145/172] REF: remove redundant merge duplicates --- .../dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt index d2eb46d44..0f8942361 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -78,9 +78,7 @@ private fun FunctionDeclaration.addReturnTypeFrom(originals: List.mergeFunctions() : List { - val fixedFunctions = map { it.mergeDuplicates() } - - val groups = fixedFunctions.groupBy { it.removeUnneededAndReturnType() } + val groups = this.groupBy { it.removeUnneededAndReturnType() } return groups.map { (functionStub, functions) -> if (functions.size == 1) { From a3c2e8b5498c02b25562ae9e646e31814f470511 Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 13:15:30 +0100 Subject: [PATCH 146/172] REF: FunctionDeclaration::removeUnneededAndReturnType => FunctionDeclaration::normalizeDeclaration --- .../dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt | 4 ++-- .../dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt index 0f8942361..82a6f55a3 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -78,7 +78,7 @@ private fun FunctionDeclaration.addReturnTypeFrom(originals: List.mergeFunctions() : List { - val groups = this.groupBy { it.removeUnneededAndReturnType() } + val groups = this.groupBy { it.normalizeDeclaration() } return groups.map { (functionStub, functions) -> if (functions.size == 1) { @@ -96,7 +96,7 @@ private fun CallSignatureDeclaration.addReturnTypeFrom(originals: List.mergeCallSignatures() : List { val fixedCallSignatures = map { it.mergeDuplicates() } - val groups = fixedCallSignatures.groupBy { it.removeUnneededAndReturnType() } + val groups = fixedCallSignatures.groupBy { it.normalizeDeclaration() } return groups.map { (callSignatureStub, callSignatures) -> if (callSignatures.size == 1) { diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt index 73205fb80..093bebb07 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt @@ -15,7 +15,7 @@ internal fun ParameterDeclaration.removeUnneeded(name: String = "") = copy( type = type.removeUnneeded() ) -internal fun CallSignatureDeclaration.removeUnneededAndReturnType() = removeUnneeded().copy( +internal fun CallSignatureDeclaration.normalizeDeclaration() = removeUnneeded().copy( type = UnionTypeDeclaration(emptyList()) //Dummy (invalid type) ) @@ -42,7 +42,7 @@ internal fun FunctionTypeDeclaration.removeUnneeded() = copy( type = type.removeUnneeded() ) -internal fun FunctionDeclaration.removeUnneededAndReturnType() = removeUnneeded().copy( +internal fun FunctionDeclaration.normalizeDeclaration() = removeUnneeded().copy( type = UnionTypeDeclaration(emptyList()) //Dummy (invalid type) ) From 4e6bd625bdea3368a31ec01902db4a176f3851bc Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 13:18:18 +0100 Subject: [PATCH 147/172] REF: removeUnneeded.kt => normalize --- .../mergeDuplicates/mergeDuplicates.kt | 2 +- .../tsLowerings/mergeDuplicates/normalize.kt | 72 +++++++++++++++++++ .../mergeDuplicates/removeUnneeded.kt | 72 ------------------- 3 files changed, 73 insertions(+), 73 deletions(-) create mode 100644 typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt delete mode 100644 typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt index 82a6f55a3..ae4fa5822 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -20,7 +20,7 @@ import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration private fun List.mergeFunctionTypes() : List { val minimizedFunctions = map { it.mergeDuplicates() } - val groups = minimizedFunctions.groupBy { it.removeUnneeded() } + val groups = minimizedFunctions.groupBy { it.normalize() } return groups.map { (combination, functions) -> if (functions.size == 1) { diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt new file mode 100644 index 000000000..984033b2f --- /dev/null +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt @@ -0,0 +1,72 @@ +package org.jetbrains.dukat.tsLowerings.mergeDuplicates + +import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration +import org.jetbrains.dukat.tsmodel.ConstructorDeclaration +import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.MemberDeclaration +import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration +import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration +import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration +import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration + +internal fun ParameterDeclaration.normalize(name: String = "") = copy( + name = name, + type = type.normalize() +) + +internal fun CallSignatureDeclaration.normalizeDeclaration() = normalize().copy( + type = UnionTypeDeclaration(emptyList()) //Dummy (invalid type) +) + +internal fun CallSignatureDeclaration.normalize() = copy( + parameters = parameters.map { parameter -> parameter.normalize(parameter.name) }, + type = type.normalize() +) + +internal fun ConstructorDeclaration.normalize() = copy( + parameters = parameters.map { it.normalize() } +) + +internal fun MemberDeclaration.normalize() : MemberDeclaration { + return when (this) { + is CallSignatureDeclaration -> this.normalize() + is ConstructorDeclaration -> this.normalize() + is FunctionDeclaration -> this.normalize() + else -> this + } +} + +internal fun FunctionTypeDeclaration.normalize() = copy( + parameters = parameters.map { it.normalize() }, + type = type.normalize() +) + +internal fun FunctionDeclaration.normalizeDeclaration() = normalize().copy( + type = UnionTypeDeclaration(emptyList()) //Dummy (invalid type) +) + +internal fun FunctionDeclaration.normalize() = copy( + parameters = parameters.map { parameter -> parameter.normalize(parameter.name) }, + type = type.normalize(), + body = null, + uid = "" +) + +internal fun UnionTypeDeclaration.normalize() = copy( + params = params.map { it.normalize() } +) + +internal fun ObjectLiteralDeclaration.normalize() = copy( + members = members.map { it.normalize() }, + uid = "" +) + +internal fun ParameterValueDeclaration.normalize() : ParameterValueDeclaration { + return when (this) { + is FunctionTypeDeclaration -> this.normalize() + is ObjectLiteralDeclaration -> this.normalize() + is UnionTypeDeclaration -> this.normalize() + else -> this + } +} diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt deleted file mode 100644 index 093bebb07..000000000 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/removeUnneeded.kt +++ /dev/null @@ -1,72 +0,0 @@ -package org.jetbrains.dukat.tsLowerings.mergeDuplicates - -import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration -import org.jetbrains.dukat.tsmodel.ConstructorDeclaration -import org.jetbrains.dukat.tsmodel.FunctionDeclaration -import org.jetbrains.dukat.tsmodel.MemberDeclaration -import org.jetbrains.dukat.tsmodel.ParameterDeclaration -import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration -import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration -import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration -import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration - -internal fun ParameterDeclaration.removeUnneeded(name: String = "") = copy( - name = name, - type = type.removeUnneeded() -) - -internal fun CallSignatureDeclaration.normalizeDeclaration() = removeUnneeded().copy( - type = UnionTypeDeclaration(emptyList()) //Dummy (invalid type) -) - -internal fun CallSignatureDeclaration.removeUnneeded() = copy( - parameters = parameters.map { parameter -> parameter.removeUnneeded(parameter.name) }, - type = type.removeUnneeded() -) - -internal fun ConstructorDeclaration.removeUnneeded() = copy( - parameters = parameters.map { it.removeUnneeded() } -) - -internal fun MemberDeclaration.removeUnneeded() : MemberDeclaration { - return when (this) { - is CallSignatureDeclaration -> this.removeUnneeded() - is ConstructorDeclaration -> this.removeUnneeded() - is FunctionDeclaration -> this.removeUnneeded() - else -> this - } -} - -internal fun FunctionTypeDeclaration.removeUnneeded() = copy( - parameters = parameters.map { it.removeUnneeded() }, - type = type.removeUnneeded() -) - -internal fun FunctionDeclaration.normalizeDeclaration() = removeUnneeded().copy( - type = UnionTypeDeclaration(emptyList()) //Dummy (invalid type) -) - -internal fun FunctionDeclaration.removeUnneeded() = copy( - parameters = parameters.map { parameter -> parameter.removeUnneeded(parameter.name) }, - type = type.removeUnneeded(), - body = null, - uid = "" -) - -internal fun UnionTypeDeclaration.removeUnneeded() = copy( - params = params.map { it.removeUnneeded() } -) - -internal fun ObjectLiteralDeclaration.removeUnneeded() = copy( - members = members.map { it.removeUnneeded() }, - uid = "" -) - -internal fun ParameterValueDeclaration.removeUnneeded() : ParameterValueDeclaration { - return when (this) { - is FunctionTypeDeclaration -> this.removeUnneeded() - is ObjectLiteralDeclaration -> this.removeUnneeded() - is UnionTypeDeclaration -> this.removeUnneeded() - else -> this - } -} From 0f9591ea1b0a9f37a0219280afbcf19fd80d2e77 Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 13:20:25 +0100 Subject: [PATCH 148/172] REF: use IRRELEVANT_UID in normalized declarations --- .../dukat/tsLowerings/mergeDuplicates/normalize.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt index 984033b2f..2778e1a5e 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt @@ -10,6 +10,8 @@ import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration +const val IRRELEVANT_UID = "" + internal fun ParameterDeclaration.normalize(name: String = "") = copy( name = name, type = type.normalize() @@ -50,7 +52,7 @@ internal fun FunctionDeclaration.normalize() = copy( parameters = parameters.map { parameter -> parameter.normalize(parameter.name) }, type = type.normalize(), body = null, - uid = "" + uid = IRRELEVANT_UID ) internal fun UnionTypeDeclaration.normalize() = copy( @@ -59,7 +61,7 @@ internal fun UnionTypeDeclaration.normalize() = copy( internal fun ObjectLiteralDeclaration.normalize() = copy( members = members.map { it.normalize() }, - uid = "" + uid = IRRELEVANT_UID ) internal fun ParameterValueDeclaration.normalize() : ParameterValueDeclaration { From 7d39973e75ee8a6a49411d7eb3f63011f0ac5a74 Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 13:28:40 +0100 Subject: [PATCH 149/172] REF: introduce IRRELEVANT_TYPE --- .../dukat/tsLowerings/mergeDuplicates/normalize.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt index 2778e1a5e..ebfeae463 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt @@ -12,13 +12,21 @@ import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration const val IRRELEVANT_UID = "" +private object IRRELEVANT_TYPE : ParameterValueDeclaration { + override val nullable: Boolean + get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates. + override var meta: ParameterValueDeclaration? + get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates. + set(_) {} +} + internal fun ParameterDeclaration.normalize(name: String = "") = copy( name = name, type = type.normalize() ) internal fun CallSignatureDeclaration.normalizeDeclaration() = normalize().copy( - type = UnionTypeDeclaration(emptyList()) //Dummy (invalid type) + type = IRRELEVANT_TYPE ) internal fun CallSignatureDeclaration.normalize() = copy( @@ -45,7 +53,7 @@ internal fun FunctionTypeDeclaration.normalize() = copy( ) internal fun FunctionDeclaration.normalizeDeclaration() = normalize().copy( - type = UnionTypeDeclaration(emptyList()) //Dummy (invalid type) + type = IRRELEVANT_TYPE ) internal fun FunctionDeclaration.normalize() = copy( From 57b4276d1394825d4ba0bfcadce75d2c965ced7d Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 13:29:42 +0100 Subject: [PATCH 150/172] REF: use rasieConcent in IRRELEVANT_TYPE getters --- .../jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt index ebfeae463..4aa812ed1 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt @@ -1,5 +1,6 @@ package org.jetbrains.dukat.tsLowerings.mergeDuplicates +import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration import org.jetbrains.dukat.tsmodel.ConstructorDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration @@ -14,9 +15,9 @@ const val IRRELEVANT_UID = "" private object IRRELEVANT_TYPE : ParameterValueDeclaration { override val nullable: Boolean - get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates. + get() = raiseConcern("Irrelevant type is not supposed to be used") { false } override var meta: ParameterValueDeclaration? - get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates. + get() = raiseConcern("Irrelevant type is not supposed to be used") { null } set(_) {} } From 535fc4d848ba440e8f7f96e6a7e1c70f511540cb Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 13:37:45 +0100 Subject: [PATCH 151/172] REF: susbtiteType while normalization --- .../mergeDuplicates/mergeDuplicates.kt | 13 +++++++-- .../tsLowerings/mergeDuplicates/normalize.kt | 28 ++++--------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt index ae4fa5822..05a194b2f 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -1,5 +1,6 @@ package org.jetbrains.dukat.tsLowerings.mergeDuplicates +import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.ConstructorDeclaration @@ -17,6 +18,14 @@ import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration import org.jetbrains.dukat.tsmodel.types.TypeDeclaration import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration +private object IRRELEVANT_TYPE : ParameterValueDeclaration { + override val nullable: Boolean + get() = raiseConcern("Irrelevant type is not supposed to be used") { false } + override var meta: ParameterValueDeclaration? + get() = raiseConcern("Irrelevant type is not supposed to be used") { null } + set(_) {} +} + private fun List.mergeFunctionTypes() : List { val minimizedFunctions = map { it.mergeDuplicates() } @@ -78,7 +87,7 @@ private fun FunctionDeclaration.addReturnTypeFrom(originals: List.mergeFunctions() : List { - val groups = this.groupBy { it.normalizeDeclaration() } + val groups = this.groupBy { it.normalize(IRRELEVANT_TYPE) } return groups.map { (functionStub, functions) -> if (functions.size == 1) { @@ -96,7 +105,7 @@ private fun CallSignatureDeclaration.addReturnTypeFrom(originals: List.mergeCallSignatures() : List { val fixedCallSignatures = map { it.mergeDuplicates() } - val groups = fixedCallSignatures.groupBy { it.normalizeDeclaration() } + val groups = fixedCallSignatures.groupBy { it.normalize(IRRELEVANT_TYPE) } return groups.map { (callSignatureStub, callSignatures) -> if (callSignatures.size == 1) { diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt index 4aa812ed1..0129fe734 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt @@ -13,33 +13,21 @@ import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration const val IRRELEVANT_UID = "" -private object IRRELEVANT_TYPE : ParameterValueDeclaration { - override val nullable: Boolean - get() = raiseConcern("Irrelevant type is not supposed to be used") { false } - override var meta: ParameterValueDeclaration? - get() = raiseConcern("Irrelevant type is not supposed to be used") { null } - set(_) {} -} - internal fun ParameterDeclaration.normalize(name: String = "") = copy( name = name, type = type.normalize() ) -internal fun CallSignatureDeclaration.normalizeDeclaration() = normalize().copy( - type = IRRELEVANT_TYPE -) - -internal fun CallSignatureDeclaration.normalize() = copy( +internal fun CallSignatureDeclaration.normalize(substituteType: ParameterValueDeclaration? = null) = copy( parameters = parameters.map { parameter -> parameter.normalize(parameter.name) }, - type = type.normalize() + type = substituteType ?: type.normalize() ) internal fun ConstructorDeclaration.normalize() = copy( parameters = parameters.map { it.normalize() } ) -internal fun MemberDeclaration.normalize() : MemberDeclaration { +internal fun MemberDeclaration.normalize(): MemberDeclaration { return when (this) { is CallSignatureDeclaration -> this.normalize() is ConstructorDeclaration -> this.normalize() @@ -53,13 +41,9 @@ internal fun FunctionTypeDeclaration.normalize() = copy( type = type.normalize() ) -internal fun FunctionDeclaration.normalizeDeclaration() = normalize().copy( - type = IRRELEVANT_TYPE -) - -internal fun FunctionDeclaration.normalize() = copy( +internal fun FunctionDeclaration.normalize(substituteType: ParameterValueDeclaration? = null) = copy( parameters = parameters.map { parameter -> parameter.normalize(parameter.name) }, - type = type.normalize(), + type = substituteType ?: type.normalize(), body = null, uid = IRRELEVANT_UID ) @@ -73,7 +57,7 @@ internal fun ObjectLiteralDeclaration.normalize() = copy( uid = IRRELEVANT_UID ) -internal fun ParameterValueDeclaration.normalize() : ParameterValueDeclaration { +internal fun ParameterValueDeclaration.normalize(): ParameterValueDeclaration { return when (this) { is FunctionTypeDeclaration -> this.normalize() is ObjectLiteralDeclaration -> this.normalize() From 7ed8d4b8dd0dcd92e2417e3680737488421e064c Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 14:01:14 +0100 Subject: [PATCH 152/172] private fun List.combinedReturnType(): ParameterValueDeclaration --- .../mergeDuplicates/mergeDuplicates.kt | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt index 05a194b2f..9466d6f06 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -82,9 +82,8 @@ private fun ParameterValueDeclaration.mergeDuplicates() : ParameterValueDeclarat } } -private fun FunctionDeclaration.addReturnTypeFrom(originals: List) = copy( - type = UnionTypeDeclaration(originals.map { it.type }).mergeUnion() -) +private fun List.combinedReturnType(): ParameterValueDeclaration + = UnionTypeDeclaration(this.map { it.type }).mergeUnion() private fun List.mergeFunctions() : List { val groups = this.groupBy { it.normalize(IRRELEVANT_TYPE) } @@ -93,7 +92,9 @@ private fun List.mergeFunctions() : List mergeDuplicates() + is FunctionDeclaration -> mergeDuplicates() + is VariableDeclaration -> mergeDuplicates() + else -> this + } +} + private fun List.mergeTopLevelDeclarations() : List { + map { declaration -> + declaration.mergeDuplicates() + } + + val otherDeclarations = mutableListOf() val classes = mutableListOf() val functions = mutableListOf() From 077bc2f792aad2588cacdaae67917d3daecd9478 Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 14:04:34 +0100 Subject: [PATCH 153/172] REF: reintroduceUIDs has optional uid param --- .../tsLowerings/mergeDuplicates/mergeDuplicates.kt | 2 +- .../tsLowerings/mergeDuplicates/reintroduceUIDs.kt | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt index 9466d6f06..cea1ea17e 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -94,7 +94,7 @@ private fun List.mergeFunctions() : List this.reintroduceUIDs() else -> this } -} - -internal fun FunctionDeclaration.reintroduceUIDsFromSource(source: FunctionDeclaration) = reintroduceUIDs().copy( - uid = source.uid -) \ No newline at end of file +} \ No newline at end of file From 6aa688ee6408d6923401c498db2123a27cc43d1d Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 14:09:13 +0100 Subject: [PATCH 154/172] Use UUID for random uid generation --- .../jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt index fe5a0d393..9d59007f5 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt @@ -1,7 +1,7 @@ package org.jetbrains.dukat.tsLowerings.mergeDuplicates -private var uid = 0; +import java.util.* internal fun getNewUID() : String { - return "reintroduced_uid_${uid++}" + return UUID.randomUUID().toString() } \ No newline at end of file From d1bdd90bd95a87401b806a9eaefff2bafd52ddce Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 14:16:32 +0100 Subject: [PATCH 155/172] in List.mergeFunctions() we don't need to reintroduceUIDs (but rather relying on the first item in a bucket) --- .../dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt index cea1ea17e..4e0084f3e 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -88,13 +88,11 @@ private fun List.combinedReturnType(): ParameterValueDeclar private fun List.mergeFunctions() : List { val groups = this.groupBy { it.normalize(IRRELEVANT_TYPE) } - return groups.map { (functionStub, functions) -> + return groups.map { (_, functions) -> if (functions.size == 1) { functions[0] } else { - functionStub.copy( - type = functions.combinedReturnType() - ).reintroduceUIDs(functions[0].uid) + functions[0].copy(type = functions.combinedReturnType()) } } } From d42f86f34f56274ec2497bb96abd6663e0996eee Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 14:18:01 +0100 Subject: [PATCH 156/172] in List.mergeCallSignatures() we don't need to reintroduceUIDs (but rather relying on the first item in a bucket) --- .../dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt index 4e0084f3e..907e06b8c 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -106,11 +106,11 @@ private fun List.mergeCallSignatures() : List + return groups.map { (_, callSignatures) -> if (callSignatures.size == 1) { callSignatures[0] } else { - callSignatureStub.addReturnTypeFrom(callSignatures).reintroduceUIDs() + callSignatures[0].addReturnTypeFrom(callSignatures) } } } From 33cbfa285ff705265cabef1d4ee8cdde75336571 Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 14:19:39 +0100 Subject: [PATCH 157/172] remove reintroduceUIDs and getNewUID --- .../tsLowerings/mergeDuplicates/getNewUID.kt | 7 --- .../mergeDuplicates/reintroduceUIDs.kt | 58 ------------------- 2 files changed, 65 deletions(-) delete mode 100644 typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt delete mode 100644 typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/reintroduceUIDs.kt diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt deleted file mode 100644 index 9d59007f5..000000000 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/getNewUID.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.jetbrains.dukat.tsLowerings.mergeDuplicates - -import java.util.* - -internal fun getNewUID() : String { - return UUID.randomUUID().toString() -} \ No newline at end of file diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/reintroduceUIDs.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/reintroduceUIDs.kt deleted file mode 100644 index 6276451f1..000000000 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/reintroduceUIDs.kt +++ /dev/null @@ -1,58 +0,0 @@ -package org.jetbrains.dukat.tsLowerings.mergeDuplicates - -import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration -import org.jetbrains.dukat.tsmodel.FunctionDeclaration -import org.jetbrains.dukat.tsmodel.MemberDeclaration -import org.jetbrains.dukat.tsmodel.ParameterDeclaration -import org.jetbrains.dukat.tsmodel.TypeParameterDeclaration -import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration -import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration -import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration -import org.jetbrains.dukat.tsmodel.types.UnionTypeDeclaration - -private fun ParameterDeclaration.reintroduceUIDs() = copy( - type = type.reintroduceUIDs() -) - -private fun FunctionTypeDeclaration.reintroduceUIDs() = copy( - type = type.reintroduceUIDs(), - parameters = parameters.map { it.reintroduceUIDs() } -) - -private fun ObjectLiteralDeclaration.reintroduceUIDs() = copy( - members = members.map { it.reintroduceUIDs() }, - uid = getNewUID() -) - -internal fun FunctionDeclaration.reintroduceUIDs(uid: String = getNewUID()) = copy( - type = type.reintroduceUIDs(), - parameters = parameters.map { it.reintroduceUIDs() }, - uid = uid -) - -internal fun CallSignatureDeclaration.reintroduceUIDs() = copy( - type = type.reintroduceUIDs(), - parameters = parameters.map { it.reintroduceUIDs() } -) - -private fun UnionTypeDeclaration.reintroduceUIDs() = copy( - params = params.map { it.reintroduceUIDs() } -) - -internal fun MemberDeclaration.reintroduceUIDs(): MemberDeclaration { - return when (this) { - is FunctionDeclaration -> this.reintroduceUIDs() - is ObjectLiteralDeclaration -> this.reintroduceUIDs() - is CallSignatureDeclaration -> this.reintroduceUIDs() - else -> this - } -} - -internal fun ParameterValueDeclaration.reintroduceUIDs(): ParameterValueDeclaration { - return when (this) { - is FunctionTypeDeclaration -> this.reintroduceUIDs() - is ObjectLiteralDeclaration -> this.reintroduceUIDs() - is UnionTypeDeclaration -> this.reintroduceUIDs() - else -> this - } -} \ No newline at end of file From 2c3c5256ff6062ed8864e20f59054aa119fb7ffd Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 14:22:33 +0100 Subject: [PATCH 158/172] uid.kt => generateUID and using UUID.randomUUID().toString() --- .../type/constraint/resolution/constraintToDeclaration.kt | 8 ++++---- .../dukat/js/type/constraint/resolution/generateUID.kt | 7 +++++++ .../jetbrains/dukat/js/type/constraint/resolution/uid.kt | 7 ------- 3 files changed, 11 insertions(+), 11 deletions(-) create mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/generateUID.kt delete mode 100644 javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/uid.kt diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index 4096bc5fa..c050ead21 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -49,7 +49,7 @@ private fun getVariableDeclaration(name: String, type: ParameterValueDeclaration type = type, modifiers = modifiers, initializer = null, - uid = getUID() + uid = generateUID() ) private fun getPropertyDeclaration(name: String, type: ParameterValueDeclaration, isStatic: Boolean) = PropertyDeclaration( @@ -77,7 +77,7 @@ private fun FunctionConstraint.toDeclarations(name: String, modifiers: List { private fun ObjectConstraint.toType() : ObjectLiteralDeclaration { return ObjectLiteralDeclaration( members = mapMembers(), - uid = getUID() + uid = generateUID() ) } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/generateUID.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/generateUID.kt new file mode 100644 index 000000000..1e317ef42 --- /dev/null +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/generateUID.kt @@ -0,0 +1,7 @@ +package org.jetbrains.dukat.js.type.constraint.resolution + +import java.util.* + +internal fun generateUID(): String { + return UUID.randomUUID().toString() +} \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/uid.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/uid.kt deleted file mode 100644 index a702fe10b..000000000 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/uid.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.jetbrains.dukat.js.type.constraint.resolution - -private var uid = 0; - -internal fun getUID() : String { - return uid++.toString() -} \ No newline at end of file From 4245bccbc8041ae3109fb7fefd6a2102859adfda Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 14:29:58 +0100 Subject: [PATCH 159/172] Introduce FunctionLikeDeclaration and maked FunctionDeclaration and CallSignatureDeclaration it implementors --- .../jetbrains/dukat/tsmodel/CallSignatureDeclaration.kt | 8 ++++---- .../org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt | 8 ++++---- .../jetbrains/dukat/tsmodel/FunctionLikeDeclaration.kt | 9 +++++++++ 3 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionLikeDeclaration.kt diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/CallSignatureDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/CallSignatureDeclaration.kt index 270018c67..7628946db 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/CallSignatureDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/CallSignatureDeclaration.kt @@ -3,7 +3,7 @@ package org.jetbrains.dukat.tsmodel import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration data class CallSignatureDeclaration( - val parameters: List, - val type: ParameterValueDeclaration, - val typeParameters: List -) : MemberDeclaration, ParameterOwnerDeclaration \ No newline at end of file + override val parameters: List, + override val type: ParameterValueDeclaration, + override val typeParameters: List +) : MemberDeclaration, ParameterOwnerDeclaration, FunctionLikeDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt index 679e1fbbe..c5eafdfc6 100644 --- a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionDeclaration.kt @@ -4,10 +4,10 @@ import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration data class FunctionDeclaration( val name: String, - val parameters: List, - val type: ParameterValueDeclaration, - val typeParameters: List, + override val parameters: List, + override val type: ParameterValueDeclaration, + override val typeParameters: List, val modifiers: List, val body: BlockDeclaration?, override val uid: String -) : MemberDeclaration, TopLevelDeclaration, WithUidDeclaration, ParameterOwnerDeclaration, ExpressionDeclaration \ No newline at end of file +) : MemberDeclaration, TopLevelDeclaration, WithUidDeclaration, ParameterOwnerDeclaration, ExpressionDeclaration, FunctionLikeDeclaration \ No newline at end of file diff --git a/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionLikeDeclaration.kt b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionLikeDeclaration.kt new file mode 100644 index 000000000..8bbe3c74c --- /dev/null +++ b/typescript/ts-model/src/org/jetbrains/dukat/tsmodel/FunctionLikeDeclaration.kt @@ -0,0 +1,9 @@ +package org.jetbrains.dukat.tsmodel + +import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration + +interface FunctionLikeDeclaration { + val parameters: List + val type: ParameterValueDeclaration + val typeParameters: List +} \ No newline at end of file From ae79ab6dec0f6d99105bf391190164c2866e22d8 Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 14:33:35 +0100 Subject: [PATCH 160/172] Use combinedReturnType in List.mergeCallSignatures() --- .../dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt | 9 +++------ .../dukat/tsLowerings/mergeDuplicates/normalize.kt | 1 - 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt index 907e06b8c..73582de9e 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -5,6 +5,7 @@ import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.ConstructorDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.FunctionLikeDeclaration import org.jetbrains.dukat.tsmodel.MemberDeclaration import org.jetbrains.dukat.tsmodel.ModuleDeclaration import org.jetbrains.dukat.tsmodel.ParameterDeclaration @@ -82,7 +83,7 @@ private fun ParameterValueDeclaration.mergeDuplicates() : ParameterValueDeclarat } } -private fun List.combinedReturnType(): ParameterValueDeclaration +private fun List.combinedReturnType(): ParameterValueDeclaration = UnionTypeDeclaration(this.map { it.type }).mergeUnion() private fun List.mergeFunctions() : List { @@ -97,10 +98,6 @@ private fun List.mergeFunctions() : List) = copy( - type = UnionTypeDeclaration(originals.map { it.type }).mergeUnion() -) - private fun List.mergeCallSignatures() : List { val fixedCallSignatures = map { it.mergeDuplicates() } @@ -110,7 +107,7 @@ private fun List.mergeCallSignatures() : List Date: Thu, 2 Jan 2020 14:47:00 +0100 Subject: [PATCH 161/172] raiseConcern for Interface and ModuleDeclarations --- .../jetbrains/dukat/js/type/analysis/calculateConstraints.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt index 0c2d3c047..aa7e477e6 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt @@ -69,8 +69,6 @@ fun TopLevelDeclaration.calculateConstraints(owner: PropertyOwner, path: PathWal is BlockDeclaration -> return this.calculateConstraints(owner, path) is ReturnStatementDeclaration -> return this.calculateConstraints(owner, path) is ThrowStatementDeclaration -> return this.calculateConstraints(owner, path) - is InterfaceDeclaration, - is ModuleDeclaration -> { /* These statements aren't supported in JS (ignore them) */ } else -> raiseConcern("Unexpected top level entity type <${this::class}>") { } } From 0a174ec9a45789cdebbbb19b9624842a1eb96aeb Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 14:52:54 +0100 Subject: [PATCH 162/172] Direction.Left and Direction.Right instead of First and Second --- .../jetbrains/dukat/js/type/analysis/PathDescriptor.kt | 10 +++++----- .../dukat/js/type/analysis/calculateConstraints.kt | 9 ++++----- .../org/jetbrains/dukat/js/type/analysis/expression.kt | 8 ++++---- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt index 573472acb..431a30d10 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt @@ -10,8 +10,8 @@ class PathWalker { return if (directions.lastIndex >= 0) { val lastDirection = directions[directions.lastIndex] - if (lastDirection == Direction.First) { - directions[directions.lastIndex] = Direction.Second + if (lastDirection == Direction.Left) { + directions[directions.lastIndex] = Direction.Right true } else { directions.removeAt(directions.lastIndex) @@ -24,14 +24,14 @@ class PathWalker { fun getNextDirection() : Direction { if (directions.size <= position) { - directions.add(Direction.First) + directions.add(Direction.Left) } return directions[position++] } enum class Direction { - First, - Second + Left, + Right } } \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt index aa7e477e6..9b77e3325 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt @@ -11,7 +11,6 @@ import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.ExpressionStatementDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.IfStatementDeclaration -import org.jetbrains.dukat.tsmodel.InterfaceDeclaration import org.jetbrains.dukat.tsmodel.ModuleDeclaration import org.jetbrains.dukat.tsmodel.ReturnStatementDeclaration import org.jetbrains.dukat.tsmodel.ThrowStatementDeclaration @@ -31,8 +30,8 @@ fun IfStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: Path condition.calculateConstraints(owner, path) return when (path.getNextDirection()) { - PathWalker.Direction.First -> thenStatement.calculateConstraints(owner, path) - PathWalker.Direction.Second -> elseStatement?.calculateConstraints(owner, path) + PathWalker.Direction.Left -> thenStatement.calculateConstraints(owner, path) + PathWalker.Direction.Right -> elseStatement?.calculateConstraints(owner, path) } } @@ -40,8 +39,8 @@ fun WhileStatementDeclaration.calculateConstraints(owner: PropertyOwner, path: P condition.calculateConstraints(owner, path) return when (path.getNextDirection()) { - PathWalker.Direction.First -> statement.calculateConstraints(owner, path) - PathWalker.Direction.Second -> null + PathWalker.Direction.Left -> statement.calculateConstraints(owner, path) + PathWalker.Direction.Right -> null } } diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 6c24211f0..3d3973b2c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -110,11 +110,11 @@ fun BinaryExpressionDeclaration.calculateConstraints(owner: PropertyOwner, path: // Non-assignments "&&", "||" -> { when (path.getNextDirection()) { - PathWalker.Direction.First -> { + PathWalker.Direction.Left -> { left.calculateConstraints(owner, path) //right isn't being evaluated } - PathWalker.Direction.Second -> { + PathWalker.Direction.Right -> { left.calculateConstraints(owner, path) right.calculateConstraints(owner, path) } @@ -214,8 +214,8 @@ fun ConditionalExpressionDeclaration.calculateConstraints(owner: PropertyOwner, condition.calculateConstraints(owner, path) return when (path.getNextDirection()) { - PathWalker.Direction.First -> whenTrue.calculateConstraints(owner, path) - PathWalker.Direction.Second -> whenFalse.calculateConstraints(owner, path) + PathWalker.Direction.Left -> whenTrue.calculateConstraints(owner, path) + PathWalker.Direction.Right -> whenFalse.calculateConstraints(owner, path) } } From e913c7988c5fc8fb9a122a65b684b43b0d11159f Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 14:55:47 +0100 Subject: [PATCH 163/172] idiomatic nonEmpty check in PathDescriptor --- .../src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt index 431a30d10..b8c58c634 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/PathDescriptor.kt @@ -7,7 +7,7 @@ class PathWalker { tailrec fun startNextPath() : Boolean { position = 0 - return if (directions.lastIndex >= 0) { + return if (directions.isNotEmpty()) { val lastDirection = directions[directions.lastIndex] if (lastDirection == Direction.Left) { From 639ae9e1801f73a2f0aa209fced3426ed75adc1d Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 15:15:06 +0100 Subject: [PATCH 164/172] Use optional call instead of unsafe type case body.calculateConstraints --- .../src/org/jetbrains/dukat/js/type/analysis/expression.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 3d3973b2c..cf76b12d1 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -55,7 +55,7 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) : FunctionConstraint? { parameters[i].name to parameterConstraint } - val returnTypeConstraints = body!!.calculateConstraints(functionScope, pathWalker) ?: VoidTypeConstraint + val returnTypeConstraints = body?.calculateConstraints(functionScope, pathWalker) ?: VoidTypeConstraint versions.add(FunctionConstraint.Overload( returnConstraints = returnTypeConstraints, From 3a7d9fb4c101f871562f8a3e9b81802e20466034 Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 15:17:35 +0100 Subject: [PATCH 165/172] Use idyomatic ?.let as return type for something that otherwise returns null --- .../src/org/jetbrains/dukat/js/type/analysis/expression.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index cf76b12d1..1a2eb9a66 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -39,7 +39,7 @@ import org.jetbrains.dukat.tsmodel.expression.literal.StringLiteralExpressionDec import org.jetbrains.dukat.tsmodel.expression.name.IdentifierExpressionDeclaration fun FunctionDeclaration.addTo(owner: PropertyOwner) : FunctionConstraint? { - return if (this.body != null) { + return this.body?.let { val pathWalker = PathWalker() val versions = mutableListOf() @@ -55,7 +55,7 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) : FunctionConstraint? { parameters[i].name to parameterConstraint } - val returnTypeConstraints = body?.calculateConstraints(functionScope, pathWalker) ?: VoidTypeConstraint + val returnTypeConstraints = it.calculateConstraints(functionScope, pathWalker) ?: VoidTypeConstraint versions.add(FunctionConstraint.Overload( returnConstraints = returnTypeConstraints, @@ -70,8 +70,6 @@ fun FunctionDeclaration.addTo(owner: PropertyOwner) : FunctionConstraint? { } functionConstraint - } else { - null } } From f66f7db410488ca88e7d9861b2c58b7dd33b97ea Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 15:56:43 +0100 Subject: [PATCH 166/172] renamed underscored packages to camelCased ones --- .../dukat/js/type/analysis/calculateConstraints.kt | 2 +- .../src/org/jetbrains/dukat/js/type/analysis/expression.kt | 4 ++-- .../org/jetbrains/dukat/js/type/analysis/introduceTypes.kt | 6 +++--- .../src/org/jetbrains/dukat/js/type/analysis/members.kt | 2 +- .../jetbrains/dukat/js/type/analysis/resolveConstraints.kt | 2 +- .../js/type/constraint/composite/CompositeConstraint.kt | 2 +- .../dukat/js/type/constraint/properties/ClassConstraint.kt | 2 +- .../js/type/constraint/properties/FunctionConstraint.kt | 2 +- .../dukat/js/type/constraint/properties/ObjectConstraint.kt | 2 +- .../type/constraint/properties/PropertyOwnerConstraint.kt | 2 +- .../reference/PropertyOwnerReferenceConstraint.kt | 2 +- .../js/type/constraint/reference/ReferenceConstraint.kt | 2 +- .../constraint/reference/call/CallArgumentConstraint.kt | 2 +- .../type/constraint/reference/call/CallResultConstraint.kt | 2 +- .../type/constraint/resolution/constraintToDeclaration.kt | 2 +- .../BasicJSContext.kt | 4 ++-- .../CommonJSContext.kt | 4 ++-- .../TypeAnalysisContext.kt | 4 ++-- .../type/{property_owner => propertyOwner}/PropertyOwner.kt | 2 +- .../js/type/{property_owner => propertyOwner}/Scope.kt | 2 +- 20 files changed, 26 insertions(+), 26 deletions(-) rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/{export_resolution => exportResolution}/BasicJSContext.kt (83%) rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/{export_resolution => exportResolution}/CommonJSContext.kt (93%) rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/{export_resolution => exportResolution}/TypeAnalysisContext.kt (66%) rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/{property_owner => propertyOwner}/PropertyOwner.kt (98%) rename javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/{property_owner => propertyOwner}/Scope.kt (93%) diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt index 9b77e3325..753e73c69 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/calculateConstraints.kt @@ -4,7 +4,7 @@ import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.ThrowConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.BlockDeclaration import org.jetbrains.dukat.tsmodel.ClassDeclaration diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt index 1a2eb9a66..1d0d93b84 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/expression.kt @@ -5,7 +5,7 @@ import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.reference.ReferenceConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.CallableConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BigIntTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.BooleanTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint @@ -18,7 +18,7 @@ import org.jetbrains.dukat.js.type.constraint.reference.call.CallArgumentConstra import org.jetbrains.dukat.js.type.constraint.reference.call.CallResultConstraint import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint -import org.jetbrains.dukat.js.type.property_owner.Scope +import org.jetbrains.dukat.js.type.propertyOwner.Scope import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ClassDeclaration import org.jetbrains.dukat.tsmodel.ExpressionDeclaration diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt index 77d1f3e2e..f87246870 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/introduceTypes.kt @@ -1,8 +1,8 @@ package org.jetbrains.dukat.js.type.analysis -import org.jetbrains.dukat.js.type.export_resolution.CommonJSContext -import org.jetbrains.dukat.js.type.export_resolution.TypeAnalysisContext -import org.jetbrains.dukat.js.type.property_owner.Scope +import org.jetbrains.dukat.js.type.exportResolution.CommonJSContext +import org.jetbrains.dukat.js.type.exportResolution.TypeAnalysisContext +import org.jetbrains.dukat.js.type.propertyOwner.Scope import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ModuleDeclaration import org.jetbrains.dukat.tsmodel.SourceFileDeclaration diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt index db2c848d5..c92de59f3 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/members.kt @@ -3,7 +3,7 @@ package org.jetbrains.dukat.js.type.analysis import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.ConstructorDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/resolveConstraints.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/resolveConstraints.kt index 67a5638f1..f6f4f4a03 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/resolveConstraints.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/analysis/resolveConstraints.kt @@ -1,6 +1,6 @@ package org.jetbrains.dukat.js.type.analysis -import org.jetbrains.dukat.js.type.property_owner.Scope +import org.jetbrains.dukat.js.type.propertyOwner.Scope fun Scope.resolveConstraints() { propertyNames.forEach { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt index 56cf95d0e..7ccbb92a6 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt @@ -10,7 +10,7 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.StringTypeConst import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner class CompositeConstraint( override val owner: PropertyOwner, diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt index de2cb1fc0..acac8b814 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ClassConstraint.kt @@ -1,7 +1,7 @@ package org.jetbrains.dukat.js.type.constraint.properties import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner class ClassConstraint(owner: PropertyOwner, prototype: ObjectConstraint = ObjectConstraint(owner)) : PropertyOwnerConstraint(owner) { val propertyNames: Set diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt index d8ef48e8d..cb4a35b3b 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/FunctionConstraint.kt @@ -4,7 +4,7 @@ import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.RecursiveConstraint import org.jetbrains.dukat.js.type.constraint.resolution.ResolutionState -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner class FunctionConstraint( owner: PropertyOwner, diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt index ea4c81f80..9752c5c70 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/ObjectConstraint.kt @@ -1,7 +1,7 @@ package org.jetbrains.dukat.js.type.constraint.properties import org.jetbrains.dukat.js.type.constraint.Constraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner import org.jetbrains.dukat.panic.raiseConcern class ObjectConstraint( diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt index 4ab9c62fa..a3c853f8c 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/properties/PropertyOwnerConstraint.kt @@ -1,6 +1,6 @@ package org.jetbrains.dukat.js.type.constraint.properties import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner abstract class PropertyOwnerConstraint(override val owner: PropertyOwner) : PropertyOwner, ImmutableConstraint \ No newline at end of file diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt index a4ae8c18c..32e1c95a6 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/PropertyOwnerReferenceConstraint.kt @@ -3,7 +3,7 @@ package org.jetbrains.dukat.js.type.constraint.reference import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.properties.PropertyOwnerConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner abstract class PropertyOwnerReferenceConstraint(parent: PropertyOwner) : PropertyOwnerConstraint(parent) { private val modifiedProperties = LinkedHashMap() diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt index a60860cb7..da9b79382 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/ReferenceConstraint.kt @@ -4,7 +4,7 @@ import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.constraint.resolution.ResolutionState -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner import org.jetbrains.dukat.panic.raiseConcern open class ReferenceConstraint( diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt index 551200134..19c788212 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallArgumentConstraint.kt @@ -5,7 +5,7 @@ import org.jetbrains.dukat.js.type.constraint.immutable.ImmutableConstraint import org.jetbrains.dukat.js.type.constraint.composite.CompositeConstraint import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner class CallArgumentConstraint( private val owner: PropertyOwner, diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt index 359dcf680..439621000 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/reference/call/CallResultConstraint.kt @@ -5,7 +5,7 @@ import org.jetbrains.dukat.js.type.constraint.composite.UnionTypeConstraint import org.jetbrains.dukat.js.type.constraint.immutable.resolved.NoTypeConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.constraint.reference.PropertyOwnerReferenceConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner class CallResultConstraint( owner: PropertyOwner, diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt index c050ead21..c0008a69a 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/resolution/constraintToDeclaration.kt @@ -15,7 +15,7 @@ import org.jetbrains.dukat.js.type.constraint.immutable.resolved.VoidTypeConstra import org.jetbrains.dukat.js.type.constraint.properties.ClassConstraint import org.jetbrains.dukat.js.type.constraint.properties.FunctionConstraint import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint -import org.jetbrains.dukat.js.type.property_owner.PropertyOwner +import org.jetbrains.dukat.js.type.propertyOwner.PropertyOwner import org.jetbrains.dukat.js.type.type.anyNullableType import org.jetbrains.dukat.js.type.type.booleanType import org.jetbrains.dukat.js.type.type.nothingType diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/BasicJSContext.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/exportResolution/BasicJSContext.kt similarity index 83% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/BasicJSContext.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/exportResolution/BasicJSContext.kt index 6984f69f5..15f19c73e 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/BasicJSContext.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/exportResolution/BasicJSContext.kt @@ -1,7 +1,7 @@ -package org.jetbrains.dukat.js.type.export_resolution +package org.jetbrains.dukat.js.type.exportResolution import org.jetbrains.dukat.js.type.constraint.resolution.toDeclarations -import org.jetbrains.dukat.js.type.property_owner.Scope +import org.jetbrains.dukat.js.type.propertyOwner.Scope import org.jetbrains.dukat.tsmodel.TopLevelDeclaration class BasicJSContext : TypeAnalysisContext { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/exportResolution/CommonJSContext.kt similarity index 93% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/exportResolution/CommonJSContext.kt index d413cbbcc..18fd58cfd 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/CommonJSContext.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/exportResolution/CommonJSContext.kt @@ -1,8 +1,8 @@ -package org.jetbrains.dukat.js.type.export_resolution +package org.jetbrains.dukat.js.type.exportResolution import org.jetbrains.dukat.js.type.constraint.properties.ObjectConstraint import org.jetbrains.dukat.js.type.constraint.resolution.asDefaultToDeclarations -import org.jetbrains.dukat.js.type.property_owner.Scope +import org.jetbrains.dukat.js.type.propertyOwner.Scope import org.jetbrains.dukat.panic.raiseConcern import org.jetbrains.dukat.tsmodel.TopLevelDeclaration diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/TypeAnalysisContext.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/exportResolution/TypeAnalysisContext.kt similarity index 66% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/TypeAnalysisContext.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/exportResolution/TypeAnalysisContext.kt index 0be54bfe6..328753ea0 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/export_resolution/TypeAnalysisContext.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/exportResolution/TypeAnalysisContext.kt @@ -1,6 +1,6 @@ -package org.jetbrains.dukat.js.type.export_resolution +package org.jetbrains.dukat.js.type.exportResolution -import org.jetbrains.dukat.js.type.property_owner.Scope +import org.jetbrains.dukat.js.type.propertyOwner.Scope import org.jetbrains.dukat.tsmodel.TopLevelDeclaration interface TypeAnalysisContext { diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/propertyOwner/PropertyOwner.kt similarity index 98% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/propertyOwner/PropertyOwner.kt index 1602bab10..8ace52e61 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/PropertyOwner.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/propertyOwner/PropertyOwner.kt @@ -1,4 +1,4 @@ -package org.jetbrains.dukat.js.type.property_owner +package org.jetbrains.dukat.js.type.propertyOwner import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.analysis.PathWalker diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/propertyOwner/Scope.kt similarity index 93% rename from javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt rename to javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/propertyOwner/Scope.kt index e11fbedc2..13fea7f59 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/property_owner/Scope.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/propertyOwner/Scope.kt @@ -1,4 +1,4 @@ -package org.jetbrains.dukat.js.type.property_owner +package org.jetbrains.dukat.js.type.propertyOwner import org.jetbrains.dukat.astCommon.IdentifierEntity import org.jetbrains.dukat.js.type.constraint.Constraint From 55d4420c3d655e236622e1fab20b542b3cce6757 Mon Sep 17 00:00:00 2001 From: Shagen Ogandzhanian Date: Thu, 2 Jan 2020 17:33:31 +0100 Subject: [PATCH 167/172] Remove unused code --- .../mergeDuplicates/mergeDuplicates.kt | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt index 73582de9e..26ac19a04 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -171,22 +171,7 @@ private fun VariableDeclaration.mergeDuplicates() = copy( type = type.mergeDuplicates() ) - -private fun TopLevelDeclaration.mergeDuplicates(): TopLevelDeclaration { - return when(this) { - is ClassDeclaration -> mergeDuplicates() - is FunctionDeclaration -> mergeDuplicates() - is VariableDeclaration -> mergeDuplicates() - else -> this - } -} - private fun List.mergeTopLevelDeclarations() : List { - map { declaration -> - declaration.mergeDuplicates() - } - - val otherDeclarations = mutableListOf() val classes = mutableListOf() val functions = mutableListOf() From 2d476f40624aaa9376e826b6a0c4b87e0bbeefc1 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Fri, 3 Jan 2020 11:18:59 +0100 Subject: [PATCH 168/172] Fix some duplicates not being merged correctly --- .../mergeDuplicates/mergeDuplicates.kt | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt index 26ac19a04..8000fb3cf 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -42,20 +42,30 @@ private fun List.mergeFunctionTypes() : List.mergeObjectTypes() : List { - return map { it.mergeDuplicates() }.distinct() + return map { it.mergeDuplicates() }.distinctBy { it.normalize() } } private fun List.mergeTypeDeclarations() : List { return distinct() } +private val UnionTypeDeclaration.flatParameters : List + get() { + return params.flatMap { + when (it) { + is UnionTypeDeclaration -> it.flatParameters + else -> listOf(it) + } + } + } + private fun UnionTypeDeclaration.mergeUnion() : ParameterValueDeclaration { val types = mutableListOf() val functionTypes = mutableListOf() val objectTypes = mutableListOf() val typeDeclarations = mutableListOf() - params.forEach { + flatParameters.forEach { when (it) { is FunctionTypeDeclaration -> functionTypes += it is ObjectLiteralDeclaration -> objectTypes += it @@ -204,9 +214,6 @@ fun SourceFileDeclaration.mergeDuplicates() = copy( root = root.mergeDuplicates() ) -fun SourceSetDeclaration.mergeDuplicates() : SourceSetDeclaration { - val mergedSources = sources.map { it.mergeDuplicates() } - return copy( - sources = mergedSources - ) -} \ No newline at end of file +fun SourceSetDeclaration.mergeDuplicates() = copy( + sources = sources.map { it.mergeDuplicates() } +) \ No newline at end of file From 1e5eec44bbe487b29b76d78f3fe4078af0edbcf2 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Tue, 7 Jan 2020 13:49:17 +0100 Subject: [PATCH 169/172] Add tests for PathWalker --- javascript/js-type-analysis/build.gradle | 9 +- .../js/type/analysis/tests/PathWalkerTests.kt | 201 ++++++++++++++++++ 2 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 javascript/js-type-analysis/test/src/org/jetbrains/dukat/js/type/analysis/tests/PathWalkerTests.kt diff --git a/javascript/js-type-analysis/build.gradle b/javascript/js-type-analysis/build.gradle index b092ebeb5..cb982db55 100644 --- a/javascript/js-type-analysis/build.gradle +++ b/javascript/js-type-analysis/build.gradle @@ -1,9 +1,16 @@ plugins { - id 'kotlin' + id("kotlin") } dependencies { implementation(project(":ast-common")) implementation(project(":panic")) implementation(project(":ts-model")) + + testImplementation("org.jetbrains.kotlin:kotlin-test-common") + testImplementation("org.jetbrains.kotlin:kotlin-test-annotations-common") + testImplementation("org.jetbrains.kotlin:kotlin-test") + + testImplementation("org.junit.jupiter:junit-jupiter-params:${gradle.jupiterVersion}") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${gradle.jupiterVersion}") } \ No newline at end of file diff --git a/javascript/js-type-analysis/test/src/org/jetbrains/dukat/js/type/analysis/tests/PathWalkerTests.kt b/javascript/js-type-analysis/test/src/org/jetbrains/dukat/js/type/analysis/tests/PathWalkerTests.kt new file mode 100644 index 000000000..433f6cf66 --- /dev/null +++ b/javascript/js-type-analysis/test/src/org/jetbrains/dukat/js/type/analysis/tests/PathWalkerTests.kt @@ -0,0 +1,201 @@ +package org.jetbrains.dukat.js.type.analysis.tests + +import org.jetbrains.dukat.js.type.analysis.PathWalker +import org.jetbrains.dukat.js.type.analysis.PathWalker.Direction.Left +import org.jetbrains.dukat.js.type.analysis.PathWalker.Direction.Right +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals + +private data class BinaryTreeNode ( + val children: Pair? = null +) { + constructor(left: BinaryTreeNode, right: BinaryTreeNode) : this(left to right) + + val isEndNode: Boolean + get() = children == null + + val pathCount: Int + get() : Int { + return children?.let { it.first.pathCount + it.second.pathCount } ?: 1 + } + + operator fun get(direction: PathWalker.Direction) : BinaryTreeNode { + return when (direction) { + Left -> children!!.first + Right -> children!!.second + } + } +} + +class PathWalkerTests { + + private fun getPaths(rootNode: BinaryTreeNode) : List> { + val paths: MutableList> = mutableListOf() + var currentPath: MutableList = mutableListOf() + + val pathWalker = PathWalker() + + val pathCount = rootNode.pathCount + var visitedPaths = 0 + + var currentNode = rootNode + + do { + currentNode = if (currentNode.isEndNode) { + val isTraversalDone = !pathWalker.startNextPath() + paths += currentPath + currentPath = mutableListOf() + visitedPaths++ + + if (visitedPaths < pathCount) { + assert(!isTraversalDone) { "Traversal terminated early! Expected $pathCount paths, but visited $visitedPaths in tree:\n$rootNode" } + } else { + assert(isTraversalDone) { "Traversal failed to terminate correctly in tree:\n$rootNode" } + } + + rootNode + } else { + val nextDirection = pathWalker.getNextDirection() + currentPath.add(nextDirection) + currentNode[nextDirection] + } + } while (visitedPaths < pathCount) + + return paths + } + + private fun getMessage(tree: BinaryTreeNode) = "Tree failed to be walked correctly:\n$tree\n" + + private fun assertTreeWalkResult(tree: BinaryTreeNode, result: List>) { + assertEquals( + expected = result, + actual = getPaths(tree), + message = getMessage(tree) + ) + } + + @Test + fun singleNodeTree() { + assertTreeWalkResult( + tree = BinaryTreeNode(), + result = listOf(emptyList()) + ) + } + + @Test + fun simpleBalancedTree() { + assertTreeWalkResult( + tree = BinaryTreeNode( + left = BinaryTreeNode( + left = BinaryTreeNode( + left = BinaryTreeNode( + left = BinaryTreeNode(), + right = BinaryTreeNode() + ), + right = BinaryTreeNode( + left = BinaryTreeNode(), + right = BinaryTreeNode() + ) + ), + right = BinaryTreeNode( + left = BinaryTreeNode( + left = BinaryTreeNode(), + right = BinaryTreeNode() + ), + right = BinaryTreeNode( + left = BinaryTreeNode(), + right = BinaryTreeNode() + ) + ) + ), + right = BinaryTreeNode( + left = BinaryTreeNode( + left = BinaryTreeNode( + left = BinaryTreeNode(), + right = BinaryTreeNode() + ), + right = BinaryTreeNode( + left = BinaryTreeNode(), + right = BinaryTreeNode() + ) + ), + right = BinaryTreeNode( + left = BinaryTreeNode( + left = BinaryTreeNode(), + right = BinaryTreeNode() + ), + right = BinaryTreeNode( + left = BinaryTreeNode(), + right = BinaryTreeNode() + ) + ) + ) + ), + result = listOf( + listOf(Left, Left, Left, Left), + listOf(Left, Left, Left, Right), + listOf(Left, Left, Right, Left), + listOf(Left, Left, Right, Right), + listOf(Left, Right, Left, Left), + listOf(Left, Right, Left, Right), + listOf(Left, Right, Right, Left), + listOf(Left, Right, Right, Right), + listOf(Right, Left, Left, Left), + listOf(Right, Left, Left, Right), + listOf(Right, Left, Right, Left), + listOf(Right, Left, Right, Right), + listOf(Right, Right, Left, Left), + listOf(Right, Right, Left, Right), + listOf(Right, Right, Right, Left), + listOf(Right, Right, Right, Right) + ) + ) + } + + @Test + fun basicTreeLeft() { + assertTreeWalkResult( + tree = BinaryTreeNode( + left = BinaryTreeNode( + left = BinaryTreeNode( + left = BinaryTreeNode(), + right = BinaryTreeNode() + ), + right = BinaryTreeNode() + ), + right = BinaryTreeNode() + ), + + result = listOf( + listOf(Left, Left, Left), + listOf(Left, Left, Right), + listOf(Left, Right), + listOf(Right) + ) + ) + } + + @Test + fun basicTreeRight() { + assertTreeWalkResult( + tree = BinaryTreeNode( + left = BinaryTreeNode(), + right = BinaryTreeNode( + left = BinaryTreeNode(), + right = BinaryTreeNode( + left = BinaryTreeNode(), + right = BinaryTreeNode() + ) + ) + ), + + result = listOf( + listOf(Left), + listOf(Right, Left), + listOf(Right, Right, Left), + listOf(Right, Right, Right) + ) + ) + } + +} \ No newline at end of file From 195d673ce1c0c9a74ab366d30083a65fc0f42b9c Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Wed, 8 Jan 2020 14:14:35 +0100 Subject: [PATCH 170/172] Normalize properties correctly, when mergeing duplicates --- .../dukat/tsLowerings/mergeDuplicates/normalize.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt index cc8ad4794..9ed44b994 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/normalize.kt @@ -5,6 +5,7 @@ import org.jetbrains.dukat.tsmodel.ConstructorDeclaration import org.jetbrains.dukat.tsmodel.FunctionDeclaration import org.jetbrains.dukat.tsmodel.MemberDeclaration import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.types.FunctionTypeDeclaration import org.jetbrains.dukat.tsmodel.types.ObjectLiteralDeclaration import org.jetbrains.dukat.tsmodel.types.ParameterValueDeclaration @@ -31,6 +32,7 @@ internal fun MemberDeclaration.normalize(): MemberDeclaration { is CallSignatureDeclaration -> this.normalize() is ConstructorDeclaration -> this.normalize() is FunctionDeclaration -> this.normalize() + is PropertyDeclaration -> this.normalize() else -> this } } @@ -47,6 +49,10 @@ internal fun FunctionDeclaration.normalize(substituteType: ParameterValueDeclara uid = IRRELEVANT_UID ) +internal fun PropertyDeclaration.normalize() = copy( + type = type.normalize() +) + internal fun UnionTypeDeclaration.normalize() = copy( params = params.map { it.normalize() } ) From 13cf9364534c2c6cf7299629376b1c4e50ccecc4 Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Wed, 8 Jan 2020 14:21:13 +0100 Subject: [PATCH 171/172] Merge duplicates within types of properties (for example within unions) --- .../dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt index 8000fb3cf..0b8644f81 100644 --- a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/mergeDuplicates/mergeDuplicates.kt @@ -9,6 +9,7 @@ import org.jetbrains.dukat.tsmodel.FunctionLikeDeclaration import org.jetbrains.dukat.tsmodel.MemberDeclaration import org.jetbrains.dukat.tsmodel.ModuleDeclaration import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.PropertyDeclaration import org.jetbrains.dukat.tsmodel.SourceFileDeclaration import org.jetbrains.dukat.tsmodel.SourceSetDeclaration import org.jetbrains.dukat.tsmodel.TopLevelDeclaration @@ -133,6 +134,7 @@ private fun List.mergeMembers() : List { is ConstructorDeclaration -> constructors += member.mergeDuplicates() is FunctionDeclaration -> methods += member.mergeDuplicates() is CallSignatureDeclaration -> callSignatures += member.mergeDuplicates() + is PropertyDeclaration -> otherMembers += member.mergeDuplicates() else -> otherMembers += member } } @@ -151,6 +153,10 @@ private fun ParameterDeclaration.mergeDuplicates() = copy( type = type.mergeDuplicates() ) +private fun PropertyDeclaration.mergeDuplicates() = copy( + type = type.mergeDuplicates() +) + private fun ConstructorDeclaration.mergeDuplicates() = copy( parameters = parameters.map { it.mergeDuplicates() } ) From d3da83c5db2516f8d0fb9ff3ac1676067a64d11d Mon Sep 17 00:00:00 2001 From: Maximilian Seitz Date: Thu, 9 Jan 2020 16:46:14 +0100 Subject: [PATCH 172/172] Improve readability of unknown parameter names. Now named 'argA', 'argB', ..., 'argAA', 'argAB', etc. --- .../arguments/callResultModified.d.kt | 4 +- .../data/javascript/arguments/callable.d.kt | 2 +- .../dukat/js/translator/JavaScriptLowerer.kt | 4 +- .../composite/CompositeConstraint.kt | 2 +- .../nameUnnamedFunctionParameters.kt | 66 +++++++++++++++++++ 5 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/nameUnnamedFunctionParameters.kt diff --git a/compiler/test/data/javascript/arguments/callResultModified.d.kt b/compiler/test/data/javascript/arguments/callResultModified.d.kt index 977e0cae1..5e98159cc 100644 --- a/compiler/test/data/javascript/arguments/callResultModified.d.kt +++ b/compiler/test/data/javascript/arguments/callResultModified.d.kt @@ -30,6 +30,6 @@ external interface `T$1` { set(value) = definedExternally } -external fun generateVector(vectorProvider: (`0`: Any? /* = null */, `1`: Any? /* = null */, `2`: Any? /* = null */) -> `T$0`): `T$1` +external fun generateVector(vectorProvider: (Any? /* = null */, Any? /* = null */, Any? /* = null */) -> `T$0`): `T$1` -external fun generateVector(vectorProvider: (`0`: Any? /* = null */, `1`: Any? /* = null */, `2`: Any? /* = null */) -> Any?): `T$1` \ No newline at end of file +external fun generateVector(vectorProvider: (Any? /* = null */, Any? /* = null */, Any? /* = null */) -> Any?): `T$1` \ No newline at end of file diff --git a/compiler/test/data/javascript/arguments/callable.d.kt b/compiler/test/data/javascript/arguments/callable.d.kt index 2f056ba82..70eb037ef 100644 --- a/compiler/test/data/javascript/arguments/callable.d.kt +++ b/compiler/test/data/javascript/arguments/callable.d.kt @@ -15,4 +15,4 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun runOperation(numA: Number, numB: Number, operation: (`0`: Any? /* = null */, `1`: Any? /* = null */) -> Number): Number \ No newline at end of file +external fun runOperation(numA: Number, numB: Number, operation: (Any? /* = null */, Any? /* = null */) -> Number): Number \ No newline at end of file diff --git a/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt b/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt index 404d5ba92..f076857be 100644 --- a/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt +++ b/javascript/js-translator/src/org/jetbrains/dukat/js/translator/JavaScriptLowerer.kt @@ -6,6 +6,7 @@ import org.jetbrains.dukat.js.type.analysis.introduceTypes import org.jetbrains.dukat.moduleNameResolver.ModuleNameResolver import org.jetbrains.dukat.ts.translator.TypescriptLowerer import org.jetbrains.dukat.tsLowerings.mergeDuplicates.mergeDuplicates +import org.jetbrains.dukat.tsLowerings.nameUnnamedFunctionParameters import org.jetbrains.dukat.tsmodel.SourceSetDeclaration import org.jetrbains.dukat.nodeLowering.lowerings.FqNode @@ -14,7 +15,8 @@ class JavaScriptLowerer(nameResolver: ModuleNameResolver) : TypescriptLowerer(na return super.lower( sourceSet .introduceTypes() - .mergeDuplicates(), + .mergeDuplicates() + .nameUnnamedFunctionParameters(), stdLibSourceSet, renameMap, uidToFqNameMapper diff --git a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt index 7ccbb92a6..0259171bf 100644 --- a/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt +++ b/javascript/js-type-analysis/src/org/jetbrains/dukat/js/type/constraint/composite/CompositeConstraint.kt @@ -81,7 +81,7 @@ class CompositeConstraint( overloads = callableConstraints.map { callable -> FunctionConstraint.Overload( callable.returnConstraints, - List(parameterCount) { i -> "`$i`" to NoTypeConstraint } + List(parameterCount) { "" to NoTypeConstraint } ) } ) diff --git a/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/nameUnnamedFunctionParameters.kt b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/nameUnnamedFunctionParameters.kt new file mode 100644 index 000000000..f37aeaea4 --- /dev/null +++ b/typescript/ts-lowerings/src/org/jetbrains/dukat/tsLowerings/nameUnnamedFunctionParameters.kt @@ -0,0 +1,66 @@ +package org.jetbrains.dukat.tsLowerings + +import org.jetbrains.dukat.ownerContext.NodeOwner +import org.jetbrains.dukat.tsmodel.CallSignatureDeclaration +import org.jetbrains.dukat.tsmodel.FunctionDeclaration +import org.jetbrains.dukat.tsmodel.FunctionOwnerDeclaration +import org.jetbrains.dukat.tsmodel.MemberDeclaration +import org.jetbrains.dukat.tsmodel.ModuleDeclaration +import org.jetbrains.dukat.tsmodel.ParameterDeclaration +import org.jetbrains.dukat.tsmodel.ParameterOwnerDeclaration +import org.jetbrains.dukat.tsmodel.SourceFileDeclaration +import org.jetbrains.dukat.tsmodel.SourceSetDeclaration + +private class NameUnnamedFunctionParameters : DeclarationTypeLowering { + + private fun Int.asLetter() = 'A' + (this % 26) + + private fun Int.toParameterName() : String { + var num = this + var name = num.asLetter().toString() + while (num >= 26) { + num = (num - 26) / 26 + name = num.asLetter() + name + } + + return "arg$name" + } + + private fun List.lowerParameters(parameterOwner: NodeOwner) : List { + var argumentId = 0 + + return this.map { parameter -> + if (parameter.name.isEmpty()) { + parameter.copy( + name = argumentId++.toParameterName(), + type = lowerParameterValue(parameter.type, parameterOwner) + ) + } else { + lowerParameterDeclaration(parameter, parameterOwner) + } + } + } + + override fun lowerFunctionDeclaration(declaration: FunctionDeclaration, owner: NodeOwner): FunctionDeclaration { + return declaration.copy( + parameters = declaration.parameters.lowerParameters(owner.wrap(declaration)), + type = lowerParameterValue(declaration.type, owner.wrap(declaration)) + ) + } + + override fun lowerCallSignatureDeclaration(declaration: CallSignatureDeclaration, owner: NodeOwner): CallSignatureDeclaration { + return declaration.copy( + parameters = declaration.parameters.lowerParameters(owner.wrap(declaration)), + type = lowerParameterValue(declaration.type, owner.wrap(declaration)) + ) + } + +} + +fun ModuleDeclaration.nameUnnamedFunctionParameters(): ModuleDeclaration { + return NameUnnamedFunctionParameters().lowerDocumentRoot(this) +} + +fun SourceFileDeclaration.nameUnnamedFunctionParameters() = copy(root = root.nameUnnamedFunctionParameters()) + +fun SourceSetDeclaration.nameUnnamedFunctionParameters() = copy(sources = sources.map(SourceFileDeclaration::nameUnnamedFunctionParameters)) \ No newline at end of file