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;
 }