private void defineClassConstructor(ConstructorDeclarationNode constructorDeclaration, TypeBuilder typeBuilder) { var name = context.getIdentifier(constructorDeclaration.NameOffset, constructorDeclaration.NameLength); if (!name.equals(typeBuilder.Name)) { context.addError(CompileErrorId.MethodWithoutReturnType, constructorDeclaration, name); } if (constructorDeclaration.Modifiers.contains(Modifier.Static)) { // TODO: check that modifiers.size() == 1 var clinit = (MethodBuilder)typeBuilder.getMethod("<clinit>", Query.empty<TypeInfo>()); if (clinit != null) { context.addError(CompileErrorId.AlreadyDefinedStaticInitializer, constructorDeclaration, BytecodeHelper.getDisplayName(typeBuilder)); } clinit = typeBuilder.defineMethod("<clinit>"); clinit.setStatic(true); clinit.setReturnType(context.TypeSystem.VoidType); constructorDeclaration.addUserData(clinit); } else { if (typeBuilder.IsEnum) { // TODO: check if the contructor is private } var methodBuilder = lookupMethod(typeBuilder, constructorDeclaration.TypeParameters, constructorDeclaration.Parameters, "<init>"); if (methodBuilder != null) { context.addError(CompileErrorId.AlreadyDefinedConstructor, constructorDeclaration, BytecodeHelper.getDisplayName(typeBuilder)); } methodBuilder = typeBuilder.defineMethod("<init>"); methodBuilder.setReturnType(context.TypeSystem.VoidType); constructorDeclaration.addUserData(methodBuilder); setTypeParameters(methodBuilder, constructorDeclaration.getTypeParameters(), constructorDeclaration); context.MemberResolver.enterMethod(methodBuilder); try { setConstructorModifiers(constructorDeclaration, methodBuilder); if (typeBuilder.IsEnum) { var pb = methodBuilder.addParameter(context.TypeSystem.StringType); pb.setName("name$0"); pb = methodBuilder.addParameter(context.TypeSystem.IntType); pb.setName("ordinal$0"); } foreach (var p in constructorDeclaration.Parameters) { var t = CompilerHelper.resolveTypeReference(context, typeBuilder.PackageName, p.Type); var pb = methodBuilder.addParameter(t); pb.setName(context.getIdentifier(p.NameOffset, p.NameLength)); if (p.Modifier == ParameterModifier.Params) { methodBuilder.setVarargs(true); } } setMethodConstraints(constructorDeclaration.ConstraintsClauses, methodBuilder); } finally { context.MemberResolver.leaveMethod(); } } }
private void defineClassDestructor(DestructorDeclarationNode destructorDeclaration, TypeBuilder typeBuilder) { if (typeBuilder.IsEnum) { // TODO: error } var methodBuilder = (MethodBuilder)typeBuilder.getMethod("finalize", Query.empty<TypeInfo>()); if (methodBuilder != null) { context.addError(CompileErrorId.AlreadyDefinedDestructor, destructorDeclaration, BytecodeHelper.getDisplayName(typeBuilder)); } var name = context.getIdentifier(destructorDeclaration.NameOffset, destructorDeclaration.NameLength); if (!name.equals(typeBuilder.Name)) { context.addError(CompileErrorId.InvalidDestructorName, destructorDeclaration, name); } methodBuilder = typeBuilder.defineMethod("finalize"); methodBuilder.setReturnType(context.TypeSystem.VoidType); methodBuilder.setProtected(true); destructorDeclaration.addUserData(methodBuilder); }
private MethodBuilder lookupMethod(TypeBuilder typeBuilder, List<SimpleNameTypeReferenceNode> typeParameters, List<ParameterNode> parameters, String name) { var typeParams = getTypeParameterNames(typeParameters); foreach (var meth in typeBuilder.Methods) { if (!isCompatible(meth, name, typeParams, parameters)) { continue; } context.MemberResolver.enterMethod(meth); int i = 0; var paramTypes = new ArrayList<TypeInfo>(); try { foreach (var p in parameters) { var t = CompilerHelper.resolveTypeReference(context, typeBuilder.PackageName, p.Type, false, true); if (t == null) { break; } paramTypes.add(t); i++; } } finally { context.MemberResolver.leaveMethod(); } if (i < typeParams.size()) { continue; } var methodBuilder = (MethodBuilder)typeBuilder.getMethod(name, paramTypes); if (methodBuilder != null) { return methodBuilder; } } return null; }