From 263d837ef3e9dcc76ab3557156d29dbe7943f5dc Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Thu, 20 Jan 2022 16:37:51 +0800 Subject: [PATCH] refactor classType and interfaceType Signed-off-by: zhangrengao Change-Id: I21f6d90b1d238f5f0d022a0f890d04134cccce43 --- ts2panda/src/base/typeSystem.ts | 291 +++++++++++++------------------- 1 file changed, 115 insertions(+), 176 deletions(-) diff --git a/ts2panda/src/base/typeSystem.ts b/ts2panda/src/base/typeSystem.ts index 9202214563..e23843c707 100755 --- a/ts2panda/src/base/typeSystem.ts +++ b/ts2panda/src/base/typeSystem.ts @@ -145,68 +145,37 @@ export class TypeSummary extends BaseType { } } -export class ClassType extends BaseType { +export class ClassOrInterfaceType extends BaseType { modifier: number = ModifierAbstract.NONABSTRACT; // 0 -> unabstract, 1 -> abstract; - extendsHeritage: number = PrimitiveType.ANY; - implementsHeritages: Array = new Array(); - // fileds Array: [typeIndex] [public -> 0, private -> 1, protected -> 2] [readonly -> 1] - staticFields: Map> = new Map>(); - staticMethods: Map = new Map(); fields: Map> = new Map>(); methods: Map = new Map(); typeIndex: number; shiftedTypeIndex: number; - - constructor(classNode: ts.ClassDeclaration | ts.ClassExpression) { + constructor(node: ts.ClassDeclaration | ts.ClassExpression | ts.InterfaceDeclaration) { super(); this.typeIndex = this.getIndexFromTypeArrayBuffer(new PlaceHolderType()); this.shiftedTypeIndex = this.typeIndex + PrimitiveType._LENGTH; - // record type before its initialization, so its index can be recorded + // record type before its initialization, so its index can be recorded // in case there's recursive reference of this type - this.addCurrentType(classNode, this.shiftedTypeIndex); - this.fillInModifiers(classNode); - this.fillInHeritages(classNode); - this.fillInFieldsAndMethods(classNode); - this.setTypeArrayBuffer(this, this.typeIndex); + this.addCurrentType(node, this.shiftedTypeIndex); } - private fillInModifiers(node: ts.ClassDeclaration | ts.ClassExpression) { - if (node.modifiers) { - for (let modifier of node.modifiers) { - switch (modifier.kind) { - case ts.SyntaxKind.AbstractKeyword: { - this.modifier = ModifierAbstract.ABSTRACT; - break; - } - default: { - break; - } - } - } + public fillInMethods(member: ClassMemberFunction | ts.MethodSignature) { + /** + * a method like declaration in a new class must be a new type, + * create this type and add it into typeRecorder + */ + let variableNode = member.name ? member.name : undefined; + let funcType = new FunctionType(member); + if (variableNode) { + this.setVariable2Type(variableNode, funcType.shiftedTypeIndex); } - } - private fillInHeritages(node: ts.ClassDeclaration | ts.ClassExpression) { - if (node.heritageClauses) { - for (let heritage of node.heritageClauses) { - let heritageFullName = heritage.getText(); - for (let heritageType of heritage.types) { - let heritageIdentifier = heritageType.expression; - let heritageTypeIndex = this.getOrCreateRecordForDeclNode(heritageIdentifier, heritageIdentifier); - if (heritageFullName.startsWith("extends ")) { - this.extendsHeritage = heritageTypeIndex; - } else if (heritageFullName.startsWith("implements ")) { - this.implementsHeritages.push(heritageTypeIndex); - } - } - } - } + return funcType; } - private fillInFields(member: ts.PropertyDeclaration) { - let fieldName = jshelpers.getTextOfIdentifierOrLiteral(member.name); + public fillInFields(member: ts.PropertyDeclaration | ts.PropertySignature, isStatic = false) { let fieldInfo = Array(PrimitiveType.ANY, AccessFlag.PUBLIC, ModifierReadonly.NONREADONLY); - let isStatic: boolean = false; if (member.modifiers) { for (let modifier of member.modifiers) { switch (modifier.kind) { @@ -236,32 +205,77 @@ export class ClassType extends BaseType { let typeNode = member.type let memberName = member.name fieldInfo[0] = this.getOrCreateRecordForTypeNode(typeNode, memberName); + return fieldInfo; + } - if (isStatic) { - this.staticFields.set(fieldName, fieldInfo); - } else { - this.fields.set(fieldName, fieldInfo); - } + public transferFields2Literal(classTypeLiterals: Array, fileds: Map>) { + classTypeLiterals.push(new Literal(LiteralTag.INTEGER, fileds.size)); + fileds.forEach((typeInfo, name) => { + classTypeLiterals.push(new Literal(LiteralTag.STRING, name)); + classTypeLiterals.push(new Literal(LiteralTag.INTEGER, typeInfo[0])); // typeIndex + classTypeLiterals.push(new Literal(LiteralTag.INTEGER, typeInfo[1])); // accessFlag + classTypeLiterals.push(new Literal(LiteralTag.INTEGER, typeInfo[2])); // readonly + }); } - private fillInMethods(member: ClassMemberFunction) { - /** - * a method like declaration in a new class must be a new type, - * create this type and add it into typeRecorder - */ - let variableNode = member.name ? member.name : undefined; - let funcType = new FunctionType(member); - if (variableNode) { - this.setVariable2Type(variableNode, funcType.shiftedTypeIndex); + public transferMethods2Literal(classTypeLiterals: Array, methods: Map) { + classTypeLiterals.push(new Literal(LiteralTag.INTEGER, methods.size)); + methods.forEach((typeInfo, name) => { + classTypeLiterals.push(new Literal(LiteralTag.STRING, name)); + classTypeLiterals.push(new Literal(LiteralTag.INTEGER, typeInfo)); + }); + } + + public transfer2LiteralBuffer(): LiteralBuffer { + return new LiteralBuffer(); + } +} + +export class ClassType extends ClassOrInterfaceType { + extendsHeritage: number = PrimitiveType.ANY; + implementsHeritages: Array = new Array(); + // fileds Array: [typeIndex] [public -> 0, private -> 1, protected -> 2] [readonly -> 1] + staticFields: Map> = new Map>(); + staticMethods: Map = new Map(); + + constructor(classNode: ts.ClassDeclaration | ts.ClassExpression) { + super(classNode); + this.fillInModifiers(classNode); + this.fillInHeritages(classNode); + this.fillInFieldsAndMethods(classNode); + this.setTypeArrayBuffer(this, this.typeIndex); + } + + private fillInModifiers(node: ts.ClassDeclaration | ts.ClassExpression) { + if (node.modifiers) { + for (let modifier of node.modifiers) { + switch (modifier.kind) { + case ts.SyntaxKind.AbstractKeyword: { + this.modifier = ModifierAbstract.ABSTRACT; + break; + } + default: { + break; + } + } + } } + } - // Then, get the typeIndex and fill in the methods array - let typeIndex = this.tryGetTypeIndex(member); - let funcModifier = funcType.getModifier(); - if (funcModifier) { - this.staticMethods.set(funcType.getFunctionName(), typeIndex!); - } else { - this.methods.set(funcType.getFunctionName(), typeIndex!); + private fillInHeritages(node: ts.ClassDeclaration | ts.ClassExpression) { + if (node.heritageClauses) { + for (let heritage of node.heritageClauses) { + let heritageFullName = heritage.getText(); + for (let heritageType of heritage.types) { + let heritageIdentifier = heritageType.expression; + let heritageTypeIndex = this.getOrCreateRecordForDeclNode(heritageIdentifier, heritageIdentifier); + if (heritageFullName.startsWith("extends ")) { + this.extendsHeritage = heritageTypeIndex; + } else if (heritageFullName.startsWith("implements ")) { + this.implementsHeritages.push(heritageTypeIndex); + } + } + } } } @@ -273,11 +287,27 @@ export class ClassType extends BaseType { case ts.SyntaxKind.Constructor: case ts.SyntaxKind.GetAccessor: case ts.SyntaxKind.SetAccessor: { - this.fillInMethods(member); + let funcType = this.fillInMethods(member); + funcType.getModifier() ? this.staticMethods.set( + funcType.getFunctionName(), + this.tryGetTypeIndex(member)! + ) : this.methods.set( + funcType.getFunctionName(), + this.tryGetTypeIndex(member)! + ) break; } case ts.SyntaxKind.PropertyDeclaration: { - this.fillInFields(member); + let isStatic = false; + let fieldName = jshelpers.getTextOfIdentifierOrLiteral((member).name); + let filedInfo = this.fillInFields(member, isStatic); + isStatic ? this.staticFields.set( + fieldName, + filedInfo + ) : this.fields.set( + fieldName, + filedInfo + ) break; } default: @@ -301,38 +331,16 @@ export class ClassType extends BaseType { }); // record unstatic fields and methods - this.transferFields2Literal(classTypeLiterals, false); - this.transferMethods2Literal(classTypeLiterals, false); + this.transferFields2Literal(classTypeLiterals, this.fields); + this.transferMethods2Literal(classTypeLiterals, this.methods); // record static methods and fields; - this.transferFields2Literal(classTypeLiterals, true); - this.transferMethods2Literal(classTypeLiterals, true); + this.transferFields2Literal(classTypeLiterals, this.staticFields); + this.transferMethods2Literal(classTypeLiterals, this.staticMethods); classTypeBuf.addLiterals(...classTypeLiterals); return classTypeBuf; } - - private transferFields2Literal(classTypeLiterals: Array, isStatic: boolean) { - let transferredTarget: Map> = isStatic ? this.staticFields : this.fields; - - classTypeLiterals.push(new Literal(LiteralTag.INTEGER, transferredTarget.size)); - transferredTarget.forEach((typeInfo, name) => { - classTypeLiterals.push(new Literal(LiteralTag.STRING, name)); - classTypeLiterals.push(new Literal(LiteralTag.INTEGER, typeInfo[0])); // typeIndex - classTypeLiterals.push(new Literal(LiteralTag.INTEGER, typeInfo[1])); // accessFlag - classTypeLiterals.push(new Literal(LiteralTag.INTEGER, typeInfo[2])); // readonly - }); - } - - private transferMethods2Literal(classTypeLiterals: Array, isStatic: boolean) { - let transferredTarget: Map = isStatic ? this.staticMethods : this.methods; - - classTypeLiterals.push(new Literal(LiteralTag.INTEGER, transferredTarget.size)); - transferredTarget.forEach((typeInfo, name) => { - classTypeLiterals.push(new Literal(LiteralTag.STRING, name)); - classTypeLiterals.push(new Literal(LiteralTag.INTEGER, typeInfo)); - }); - } } export class ClassInstType extends BaseType { @@ -611,21 +619,11 @@ export class ObjectType extends BaseType { } } -export class InterfaceType extends BaseType { +export class InterfaceType extends ClassOrInterfaceType { heritages: Array = new Array(); - // fileds Array: [typeIndex] [public -> 0, private -> 1, protected -> 2] [readonly -> 1] - fields: Map> = new Map>(); - methods: Array = new Array(); - typeIndex: number; - shiftedTypeIndex: number; constructor(interfaceNode: ts.InterfaceDeclaration) { - super(); - this.typeIndex = this.getIndexFromTypeArrayBuffer(new PlaceHolderType()); - this.shiftedTypeIndex = this.typeIndex + PrimitiveType._LENGTH; - // record type before its initialization, so its index can be recorded - // in case there's recursive reference of this type - this.addCurrentType(interfaceNode, this.shiftedTypeIndex); + super(interfaceNode); this.fillInHeritages(interfaceNode); this.fillInFieldsAndMethods(interfaceNode); this.setTypeArrayBuffer(this, this.typeIndex); @@ -643,60 +641,22 @@ export class InterfaceType extends BaseType { } } - private fillInFields(member: ts.PropertySignature) { - let fieldName = jshelpers.getTextOfIdentifierOrLiteral(member.name); - let fieldInfo = Array(PrimitiveType.ANY, AccessFlag.PUBLIC, ModifierReadonly.NONREADONLY); - if (member.modifiers) { - for (let modifier of member.modifiers) { - switch (modifier.kind) { - case ts.SyntaxKind.PrivateKeyword: { - fieldInfo[1] = AccessFlag.PRIVATE; - break; - } - case ts.SyntaxKind.ProtectedKeyword: { - fieldInfo[1] = AccessFlag.PROTECTED; - break; - } - case ts.SyntaxKind.ReadonlyKeyword: { - fieldInfo[2] = ModifierReadonly.READONLY; - break; - } - default: - break; - } - } - } - let typeNode = member.type; - let memberName = member.name; - fieldInfo[0] = this.getOrCreateRecordForTypeNode(typeNode, memberName); - this.fields.set(fieldName, fieldInfo); - } - - private fillInMethods(member: ts.MethodSignature) { - /** - * a method like declaration in a new class must be a new type, - * create this type and add it into typeRecorder - */ - let variableNode = member.name ? member.name : undefined; - let funcType = new FunctionType(member); - if (variableNode) { - this.setVariable2Type(variableNode, funcType.shiftedTypeIndex); - } - // Then, get the typeIndex and fill in the methods array - let typeIndex = this.tryGetTypeIndex(member); - this.methods.push(typeIndex!); - } - private fillInFieldsAndMethods(node: ts.InterfaceDeclaration) { if (node.members) { for (let member of node.members) { switch (member.kind) { case ts.SyntaxKind.MethodSignature: { - this.fillInMethods(member); + let funcType = this.fillInMethods(member); + this.methods.set(funcType.getFunctionName(), this.tryGetTypeIndex(member)!); break; } case ts.SyntaxKind.PropertySignature: { - this.fillInFields(member); + let fieldName = jshelpers.getTextOfIdentifierOrLiteral((member).name); + let filedInfo = this.fillInFields(member); + this.fields.set( + fieldName, + filedInfo + ) break; } default: @@ -718,31 +678,10 @@ export class InterfaceType extends BaseType { }); // record fields and methods - this.transferFields2Literal(interfaceTypeLiterals); - this.transferMethods2Literal(interfaceTypeLiterals); + this.transferFields2Literal(interfaceTypeLiterals, this.fields); + this.transferMethods2Literal(interfaceTypeLiterals, this.methods); interfaceTypeBuf.addLiterals(...interfaceTypeLiterals); return interfaceTypeBuf; } - - private transferFields2Literal(interfaceTypeLiterals: Array) { - let transferredTarget: Map> = this.fields; - - interfaceTypeLiterals.push(new Literal(LiteralTag.INTEGER, transferredTarget.size)); - transferredTarget.forEach((typeInfo, name) => { - interfaceTypeLiterals.push(new Literal(LiteralTag.STRING, name)); - interfaceTypeLiterals.push(new Literal(LiteralTag.INTEGER, typeInfo[0])); // typeIndex - interfaceTypeLiterals.push(new Literal(LiteralTag.INTEGER, typeInfo[1])); // accessFlag - interfaceTypeLiterals.push(new Literal(LiteralTag.INTEGER, typeInfo[2])); // readonly - }); - } - - private transferMethods2Literal(interfaceTypeLiterals: Array) { - let transferredTarget: Array = this.methods; - - interfaceTypeLiterals.push(new Literal(LiteralTag.INTEGER, transferredTarget.length)); - transferredTarget.forEach(method => { - interfaceTypeLiterals.push(new Literal(LiteralTag.INTEGER, method)); - }); - } } -- Gitee