blob: ff4b05ccf5eb17ec5bc9b87e3c53cbdfb8ed5cfc [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#ifndef true
#define true 1
#define false 0
#endif
#define CFC_NEED_BASE_STRUCT_DEF
#include "CFCBase.h"
#include "CFCClass.h"
#include "CFCSymbol.h"
#include "CFCFunction.h"
#include "CFCMethod.h"
#include "CFCParcel.h"
#include "CFCDocuComment.h"
#include "CFCUtil.h"
#include "CFCVariable.h"
#include "CFCFileSpec.h"
#include "CFCJson.h"
struct CFCClass {
CFCBase base;
CFCWeakPtr parcel;
char *exposure;
char *name;
char *nickname;
int tree_grown;
CFCDocuComment *docucomment;
CFCWeakPtr parent;
struct CFCClass **children;
size_t num_kids;
CFCFunction **functions;
size_t num_functions;
CFCMethod **fresh_methods;
size_t num_fresh_meths;
CFCMethod **methods;
size_t num_methods;
CFCVariable **fresh_vars;
size_t num_fresh_vars;
CFCVariable **member_vars;
size_t num_member_vars;
CFCVariable **inert_vars;
size_t num_inert_vars;
CFCFileSpec *file_spec;
char *parent_class_name;
int is_final;
int is_inert;
int is_abstract;
char *struct_sym;
char *full_struct_sym;
char *ivars_struct;
char *full_ivars_struct;
char *ivars_func;
char *full_ivars_func;
char *full_ivars_offset;
char *short_class_var;
char *full_class_var;
char *privacy_symbol;
char *include_h;
};
// Pass down member vars to from parent to children.
static void
S_bequeath_member_vars(CFCClass *self);
// Pass down methods to from parent to children.
static void
S_bequeath_methods(CFCClass *self);
static const CFCMeta CFCCLASS_META = {
"Clownfish::CFC::Model::Class",
sizeof(CFCClass),
(CFCBase_destroy_t)CFCClass_destroy
};
CFCClass*
CFCClass_create(struct CFCParcel *parcel, const char *exposure,
const char *name, const char *nickname,
CFCDocuComment *docucomment, CFCFileSpec *file_spec,
const char *parent_class_name, int is_final, int is_inert,
int is_abstract) {
CFCClass *self = (CFCClass*)CFCBase_allocate(&CFCCLASS_META);
return CFCClass_do_create(self, parcel, exposure, name, nickname,
docucomment, file_spec, parent_class_name,
is_final, is_inert, is_abstract);
}
static int
S_validate_exposure(const char *exposure) {
if (!exposure) { return false; }
if (strcmp(exposure, "public")
&& strcmp(exposure, "parcel")
&& strcmp(exposure, "private")
) {
return false;
}
return true;
}
int
CFCClass_validate_class_name(const char *class_name) {
// The last component must contain lowercase letters (for now).
const char *last_colon = strrchr(class_name, ':');
const char *substring = last_colon ? last_colon + 1 : class_name;
for (;;substring++) {
if (*substring == 0) { return false; }
else if (*substring == ':') { return false; }
else if (CFCUtil_islower(*substring)) { break; }
}
// Must be UpperCamelCase, separated by "::".
const char *ptr = class_name;
if (!CFCUtil_isupper(*ptr)) { return false; }
while (*ptr != 0) {
if (*ptr == 0) { break; }
else if (*ptr == ':') {
ptr++;
if (*ptr != ':') { return false; }
ptr++;
if (!CFCUtil_isupper(*ptr)) { return false; }
ptr++;
}
else if (!CFCUtil_isalnum(*ptr)) { return false; }
else { ptr++; }
}
return true;
}
int
CFCClass_validate_class_name_component(const char *name) {
if (!name || !strlen(name)) { return false; }
if (!CFCClass_validate_class_name(name)) { return false; }
if (strchr(name, ':') != NULL) { return false; }
return true;
}
static int
S_validate_nickname(const char *nickname) {
// Allow all caps.
const char *ptr;
for (ptr = nickname; ; ptr++) {
if (*ptr == 0) {
if (strlen(nickname)) { return true; }
else { break; }
}
else if (!CFCUtil_isupper(*ptr)) { break; }
}
// Same as one component of a class name.
return CFCClass_validate_class_name_component(nickname);
}
CFCClass*
CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel,
const char *exposure, const char *name,
const char *nickname, CFCDocuComment *docucomment,
CFCFileSpec *file_spec, const char *parent_class_name,
int is_final, int is_inert, int is_abstract) {
CFCUTIL_NULL_CHECK(parcel);
CFCUTIL_NULL_CHECK(name);
exposure = exposure ? exposure : "parcel";
// Validate.
if (!S_validate_exposure(exposure)) {
CFCBase_decref((CFCBase*)self);
CFCUtil_die("Invalid exposure: '%s'", exposure);
}
if (!CFCClass_validate_class_name(name)) {
CFCBase_decref((CFCBase*)self);
CFCUtil_die("Invalid name: '%s'", name);
}
const char *last_colon = strrchr(name, ':');
const char *struct_sym = last_colon ? last_colon + 1 : name;
// Derive nickname if necessary, then validate.
const char *real_nickname = NULL;
if (nickname) {
real_nickname = nickname;
}
else {
real_nickname = struct_sym;
}
if (!S_validate_nickname(real_nickname)) {
CFCBase_decref((CFCBase*)self);
CFCUtil_die("Invalid nickname: '%s'", real_nickname);
}
// Default parent class name is "Clownfish::Obj".
if (!is_inert
&& !parent_class_name
&& strcmp(name, "Clownfish::Obj") != 0
) {
parent_class_name = "Clownfish::Obj";
}
// Assign.
self->parcel = CFCWeakPtr_new((CFCBase*)parcel);
self->exposure = CFCUtil_strdup(exposure);
self->name = CFCUtil_strdup(name);
self->nickname = CFCUtil_strdup(real_nickname);
self->tree_grown = false;
self->children = (CFCClass**)CALLOCATE(1, sizeof(CFCClass*));
self->num_kids = 0;
self->functions = (CFCFunction**)CALLOCATE(1, sizeof(CFCFunction*));
self->num_functions = 0;
self->fresh_methods = (CFCMethod**)CALLOCATE(1, sizeof(CFCMethod*));
self->num_fresh_meths = 0;
self->methods = NULL;
self->num_methods = 0;
self->fresh_vars = (CFCVariable**)CALLOCATE(1, sizeof(CFCVariable*));
self->num_fresh_vars = 0;
self->member_vars = NULL;
self->num_member_vars = 0;
self->inert_vars = (CFCVariable**)CALLOCATE(1, sizeof(CFCVariable*));
self->num_inert_vars = 0;
self->parent_class_name = CFCUtil_strdup(parent_class_name);
self->docucomment
= (CFCDocuComment*)CFCBase_incref((CFCBase*)docucomment);
self->file_spec = (CFCFileSpec*)CFCBase_incref((CFCBase*)file_spec);
// Cache several derived symbols.
const char *prefix = CFCClass_get_prefix(self);
self->struct_sym = CFCUtil_strdup(struct_sym);
self->full_struct_sym = CFCUtil_sprintf("%s%s", prefix, struct_sym);
self->ivars_struct = CFCUtil_sprintf("%sIVARS", struct_sym);
self->full_ivars_struct = CFCUtil_sprintf("%s%s", prefix,
self->ivars_struct);
self->ivars_func = CFCUtil_sprintf("%s_IVARS", self->nickname);
self->full_ivars_func = CFCUtil_sprintf("%s%s", prefix,
self->ivars_func);
self->full_ivars_offset = CFCUtil_sprintf("%s_OFFSET",
self->full_ivars_func);
const char *PREFIX = CFCClass_get_PREFIX(self);
size_t struct_sym_len = strlen(struct_sym);
char *short_class_var = (char*)MALLOCATE(struct_sym_len + 1);
size_t i;
for (i = 0; i < struct_sym_len; i++) {
short_class_var[i] = CFCUtil_toupper(struct_sym[i]);
}
short_class_var[struct_sym_len] = '\0';
self->short_class_var = short_class_var;
self->full_class_var = CFCUtil_sprintf("%s%s", PREFIX, short_class_var);
self->privacy_symbol = CFCUtil_sprintf("C_%s", self->full_class_var);
// Build the relative path to the autogenerated C header file.
if (file_spec) {
const char *path_part = CFCFileSpec_get_path_part(self->file_spec);
self->include_h = CFCUtil_sprintf("%s.h", path_part);
}
else {
self->include_h = CFCUtil_strdup("class.h");
}
self->is_final = !!is_final;
self->is_inert = !!is_inert;
self->is_abstract = !!is_abstract;
// Check for include flag mismatch.
if (!CFCClass_included(self) && CFCParcel_included(parcel)) {
CFCUtil_die("Class %s from source dir found in parcel %s from"
" include dir",
name, CFCParcel_get_name(parcel));
}
char *error;
CFCUTIL_TRY {
CFCParcel_add_class(parcel, self);
}
CFCUTIL_CATCH(error);
if (error) {
CFCBase_decref((CFCBase*)self);
CFCUtil_rethrow(error);
}
return self;
}
static void
S_free_cfcbase_array(CFCBase **array) {
if (array != NULL) {
for (size_t i = 0; array[i] != NULL; i++) {
CFCBase_decref(array[i]);
}
FREEMEM(array);
}
}
void
CFCClass_destroy(CFCClass *self) {
CFCWeakPtr_destroy(&self->parcel);
FREEMEM(self->exposure);
FREEMEM(self->name);
FREEMEM(self->nickname);
CFCBase_decref((CFCBase*)self->docucomment);
CFCWeakPtr_destroy(&self->parent);
CFCBase_decref((CFCBase*)self->file_spec);
S_free_cfcbase_array((CFCBase**)self->children);
S_free_cfcbase_array((CFCBase**)self->functions);
S_free_cfcbase_array((CFCBase**)self->fresh_methods);
S_free_cfcbase_array((CFCBase**)self->methods);
S_free_cfcbase_array((CFCBase**)self->fresh_vars);
S_free_cfcbase_array((CFCBase**)self->member_vars);
S_free_cfcbase_array((CFCBase**)self->inert_vars);
FREEMEM(self->parent_class_name);
FREEMEM(self->struct_sym);
FREEMEM(self->ivars_struct);
FREEMEM(self->full_ivars_struct);
FREEMEM(self->ivars_func);
FREEMEM(self->full_ivars_func);
FREEMEM(self->full_ivars_offset);
FREEMEM(self->short_class_var);
FREEMEM(self->full_struct_sym);
FREEMEM(self->full_class_var);
FREEMEM(self->privacy_symbol);
FREEMEM(self->include_h);
CFCBase_destroy((CFCBase*)self);
}
void
CFCClass_add_child(CFCClass *self, CFCClass *child) {
CFCUTIL_NULL_CHECK(child);
if (self->tree_grown) {
CFCUtil_die("Can't call add_child after grow_tree");
}
if (self->is_final) {
CFCUtil_die("Can't inherit from final class %s", self->name);
}
if (self->is_inert) {
CFCUtil_die("Can't inherit from inert class %s", self->name);
}
if (child->is_inert) {
CFCUtil_die("Inert class %s can't inherit", child->name);
}
self->num_kids++;
size_t size = (self->num_kids + 1) * sizeof(CFCClass*);
self->children = (CFCClass**)REALLOCATE(self->children, size);
self->children[self->num_kids - 1]
= (CFCClass*)CFCBase_incref((CFCBase*)child);
self->children[self->num_kids] = NULL;
// Set parent of child.
CFCWeakPtr_set(&child->parent, (CFCBase*)self);
}
void
CFCClass_add_function(CFCClass *self, CFCFunction *func) {
CFCUTIL_NULL_CHECK(func);
if (self->tree_grown) {
CFCUtil_die("Can't call add_function after grow_tree");
}
self->num_functions++;
size_t size = (self->num_functions + 1) * sizeof(CFCFunction*);
self->functions = (CFCFunction**)REALLOCATE(self->functions, size);
self->functions[self->num_functions - 1]
= (CFCFunction*)CFCBase_incref((CFCBase*)func);
self->functions[self->num_functions] = NULL;
}
void
CFCClass_add_method(CFCClass *self, CFCMethod *method) {
CFCUTIL_NULL_CHECK(method);
if (self->tree_grown) {
CFCUtil_die("Can't call add_method after grow_tree");
}
if (self->is_inert) {
CFCUtil_die("Can't add_method to an inert class");
}
self->num_fresh_meths++;
size_t size = (self->num_fresh_meths + 1) * sizeof(CFCMethod*);
self->fresh_methods = (CFCMethod**)REALLOCATE(self->fresh_methods, size);
self->fresh_methods[self->num_fresh_meths - 1]
= (CFCMethod*)CFCBase_incref((CFCBase*)method);
self->fresh_methods[self->num_fresh_meths] = NULL;
}
void
CFCClass_add_member_var(CFCClass *self, CFCVariable *var) {
CFCUTIL_NULL_CHECK(var);
if (self->tree_grown) {
CFCUtil_die("Can't call add_member_var after grow_tree");
}
self->num_fresh_vars++;
size_t size = (self->num_fresh_vars + 1) * sizeof(CFCVariable*);
self->fresh_vars = (CFCVariable**)REALLOCATE(self->fresh_vars, size);
self->fresh_vars[self->num_fresh_vars - 1]
= (CFCVariable*)CFCBase_incref((CFCBase*)var);
self->fresh_vars[self->num_fresh_vars] = NULL;
}
void
CFCClass_add_inert_var(CFCClass *self, CFCVariable *var) {
CFCUTIL_NULL_CHECK(var);
if (self->tree_grown) {
CFCUtil_die("Can't call add_inert_var after grow_tree");
}
self->num_inert_vars++;
size_t size = (self->num_inert_vars + 1) * sizeof(CFCVariable*);
self->inert_vars = (CFCVariable**)REALLOCATE(self->inert_vars, size);
self->inert_vars[self->num_inert_vars - 1]
= (CFCVariable*)CFCBase_incref((CFCBase*)var);
self->inert_vars[self->num_inert_vars] = NULL;
}
#define MAX_FUNC_LEN 128
static CFCFunction*
S_find_func(CFCFunction **funcs, const char *sym) {
if (!sym) {
return NULL;
}
for (size_t i = 0; funcs[i] != NULL; i++) {
CFCFunction *func = funcs[i];
if (strcmp(sym, CFCFunction_get_name(func)) == 0) {
return func;
}
}
return NULL;
}
CFCFunction*
CFCClass_function(CFCClass *self, const char *sym) {
return S_find_func(self->functions, sym);
}
CFCMethod*
CFCClass_method(CFCClass *self, const char *sym) {
return (CFCMethod*)S_find_func((CFCFunction**)self->methods, sym);
}
CFCMethod*
CFCClass_fresh_method(CFCClass *self, const char *sym) {
return (CFCMethod*)S_find_func((CFCFunction**)self->fresh_methods, sym);
}
void
CFCClass_resolve_types(CFCClass *self) {
for (size_t i = 0; self->functions[i] != NULL; i++) {
CFCFunction_resolve_types(self->functions[i]);
}
for (size_t i = 0; self->fresh_methods[i] != NULL; i++) {
CFCMethod_resolve_types(self->fresh_methods[i]);
}
for (size_t i = 0; self->fresh_vars[i] != NULL; i++) {
CFCVariable_resolve_type(self->fresh_vars[i]);
}
for (size_t i = 0; self->inert_vars[i] != NULL; i++) {
CFCVariable_resolve_type(self->inert_vars[i]);
}
}
// Pass down member vars to from parent to children.
static void
S_bequeath_member_vars(CFCClass *self) {
for (size_t i = 0; self->children[i] != NULL; i++) {
CFCClass *child = self->children[i];
size_t num_vars = self->num_member_vars + child->num_fresh_vars;
size_t size = (num_vars + 1) * sizeof(CFCVariable*);
child->member_vars
= (CFCVariable**)REALLOCATE(child->member_vars, size);
memcpy(child->member_vars, self->member_vars,
self->num_member_vars * sizeof(CFCVariable*));
memcpy(child->member_vars + self->num_member_vars,
child->fresh_vars,
child->num_fresh_vars * sizeof(CFCVariable*));
for (size_t j = 0; j < num_vars; j++) {
CFCBase_incref((CFCBase*)child->member_vars[j]);
}
child->num_member_vars = num_vars;
child->member_vars[num_vars] = NULL;
S_bequeath_member_vars(child);
}
}
static void
S_bequeath_methods(CFCClass *self) {
for (size_t child_num = 0; self->children[child_num] != NULL; child_num++) {
CFCClass *child = self->children[child_num];
// Create array of methods, preserving exact order so vtables match up.
size_t num_methods = 0;
size_t max_methods = self->num_methods + child->num_fresh_meths;
CFCMethod **methods = (CFCMethod**)MALLOCATE(
(max_methods + 1) * sizeof(CFCMethod*));
// Gather methods which child inherits or overrides.
for (size_t i = 0; i < self->num_methods; i++) {
CFCMethod *method = self->methods[i];
const char *meth_name = CFCMethod_get_name(method);
CFCMethod *child_method = CFCClass_fresh_method(child, meth_name);
if (child_method) {
CFCMethod_override(child_method, method);
methods[num_methods++] = child_method;
}
else {
methods[num_methods++] = method;
}
}
// Append novel child methods to array. Child methods which were just
// marked via CFCMethod_override() a moment ago are skipped.
for (size_t i = 0; i < child->num_fresh_meths; i++) {
CFCMethod *method = child->fresh_methods[i];
if (CFCMethod_novel(method)) {
methods[num_methods++] = method;
}
}
methods[num_methods] = NULL;
// Manage refcounts and assign new array. Transform to final methods
// if child class is a final class.
if (child->is_final) {
for (size_t i = 0; i < num_methods; i++) {
if (CFCMethod_final(methods[i])) {
CFCBase_incref((CFCBase*)methods[i]);
}
else {
methods[i] = CFCMethod_finalize(methods[i]);
}
}
}
else {
for (size_t i = 0; i < num_methods; i++) {
CFCBase_incref((CFCBase*)methods[i]);
}
}
child->methods = methods;
child->num_methods = num_methods;
// Pass it all down to the next generation.
S_bequeath_methods(child);
child->tree_grown = true;
}
}
static CFCBase**
S_copy_cfcbase_array(CFCBase **array, size_t num_elems) {
CFCBase **copy = (CFCBase**)MALLOCATE((num_elems + 1) * sizeof(CFCBase*));
for (size_t i = 0; i < num_elems; i++) {
copy[i] = CFCBase_incref(array[i]);
}
copy[num_elems] = NULL;
return copy;
}
void
CFCClass_grow_tree(CFCClass *self) {
if (self->tree_grown) {
CFCUtil_die("Can't call grow_tree more than once");
}
// Copy fresh variabless for root class.
self->member_vars
= (CFCVariable**)S_copy_cfcbase_array((CFCBase**)self->fresh_vars,
self->num_fresh_vars);
self->num_member_vars = self->num_fresh_vars;
S_bequeath_member_vars(self);
// Copy fresh methods for root class.
self->methods
= (CFCMethod**)S_copy_cfcbase_array((CFCBase**)self->fresh_methods,
self->num_fresh_meths);
self->num_methods = self->num_fresh_meths;
S_bequeath_methods(self);
self->tree_grown = 1;
}
void
CFCClass_read_host_data_json(CFCClass *self, CFCJson *hash, const char *path) {
CFCJson *method_hash = CFCJson_find_hash_elem(hash, "methods");
if (!method_hash) { return; }
CFCJson **children = CFCJson_get_children(method_hash);
for (int i = 0; children[i]; i += 2) {
const char *method_name = CFCJson_get_string(children[i]);
CFCMethod *method = CFCClass_method(self, method_name);
if (!method) {
CFCUtil_die("Method '%s' in '%s' not found", method_name, path);
}
CFCMethod_read_host_data_json(method, children[i+1], path);
}
}
CFCMethod**
CFCClass_fresh_methods(CFCClass *self) {
return self->fresh_methods;
}
CFCVariable**
CFCClass_fresh_member_vars(CFCClass *self) {
return self->fresh_vars;
}
CFCClass**
CFCClass_children(CFCClass *self) {
return self->children;
}
CFCFunction**
CFCClass_functions(CFCClass *self) {
return self->functions;
}
CFCMethod**
CFCClass_methods(CFCClass *self) {
if (!self->tree_grown) {
CFCUtil_die("Can't call 'methods' before 'grow_tree'");
}
return self->methods;
}
size_t
CFCClass_num_methods(CFCClass *self) {
if (!self->tree_grown) {
CFCUtil_die("Can't call 'num_methods' before 'grow_tree'");
}
return self->num_methods;
}
CFCVariable**
CFCClass_member_vars(CFCClass *self) {
if (!self->tree_grown) {
CFCUtil_die("Can't call 'member_vars' before 'grow_tree'");
}
return self->member_vars;
}
size_t
CFCClass_num_member_vars(CFCClass *self) {
if (!self->tree_grown) {
CFCUtil_die("Can't call 'num_member_vars' before 'grow_tree'");
}
return self->num_member_vars;
}
// Count the number of member variables declared in ancestor classes
// outside this package.
size_t
CFCClass_num_non_package_ivars(CFCClass *self) {
CFCParcel *parcel = CFCClass_get_parcel(self);
CFCClass *ancestor = CFCClass_get_parent(self);
size_t num_non_package_members = 0;
while (ancestor && CFCClass_get_parcel(ancestor) == parcel) {
ancestor = CFCClass_get_parent(ancestor);
}
if (ancestor) {
num_non_package_members = CFCClass_num_member_vars(ancestor);
}
return num_non_package_members;
}
CFCVariable**
CFCClass_inert_vars(CFCClass *self) {
return self->inert_vars;
}
const char*
CFCClass_get_nickname(CFCClass *self) {
return self->nickname;
}
CFCClass*
CFCClass_get_parent(CFCClass *self) {
return (CFCClass*)CFCWeakPtr_deref(self->parent);
}
const char*
CFCClass_get_source_dir(CFCClass *self) {
return self->file_spec
? CFCFileSpec_get_source_dir(self->file_spec)
: NULL;
}
const char*
CFCClass_get_path_part(CFCClass *self) {
return self->file_spec ? CFCFileSpec_get_path_part(self->file_spec) : NULL;
}
int
CFCClass_included(CFCClass *self) {
return self->file_spec ? CFCFileSpec_included(self->file_spec) : 0;
}
const char*
CFCClass_get_parent_class_name(CFCClass *self) {
return self->parent_class_name;
}
int
CFCClass_final(CFCClass *self) {
return self->is_final;
}
int
CFCClass_inert(CFCClass *self) {
return self->is_inert;
}
int
CFCClass_abstract(CFCClass *self) {
return self->is_abstract;
}
int
CFCClass_in_parcel(CFCClass *self, struct CFCParcel *parcel) {
return CFCClass_get_parcel(self) == parcel;
}
int
CFCClass_in_same_parcel(CFCClass *self, CFCClass *other) {
return CFCClass_get_parcel(self) == CFCClass_get_parcel(other);
}
const char*
CFCClass_get_struct_sym(CFCClass *self) {
return self->struct_sym;
}
const char*
CFCClass_full_struct_sym(CFCClass *self) {
return self->full_struct_sym;
}
const char*
CFCClass_short_ivars_struct(CFCClass *self) {
return self->ivars_struct;
}
const char*
CFCClass_full_ivars_struct(CFCClass *self) {
return self->full_ivars_struct;
}
const char*
CFCClass_short_ivars_func(CFCClass *self) {
return self->ivars_func;
}
const char*
CFCClass_full_ivars_func(CFCClass *self) {
return self->full_ivars_func;
}
const char*
CFCClass_full_ivars_offset(CFCClass *self) {
return self->full_ivars_offset;
}
const char*
CFCClass_short_class_var(CFCClass *self) {
return self->short_class_var;
}
const char*
CFCClass_full_class_var(CFCClass *self) {
return self->full_class_var;
}
const char*
CFCClass_privacy_symbol(CFCClass *self) {
return self->privacy_symbol;
}
const char*
CFCClass_include_h(CFCClass *self) {
return self->include_h;
}
CFCParcel*
CFCClass_get_parcel(CFCClass *self) {
return (CFCParcel*)CFCWeakPtr_deref(self->parcel);
}
const char*
CFCClass_get_prefix(CFCClass *self) {
return CFCParcel_get_prefix(CFCClass_get_parcel(self));
}
const char*
CFCClass_get_Prefix(CFCClass *self) {
return CFCParcel_get_Prefix(CFCClass_get_parcel(self));
}
const char*
CFCClass_get_PREFIX(CFCClass *self) {
return CFCParcel_get_PREFIX(CFCClass_get_parcel(self));
}
const char*
CFCClass_get_exposure(CFCClass *self) {
return self->exposure;
}
int
CFCClass_public(CFCClass *self) {
return !strcmp(self->exposure, "public");
}
const char*
CFCClass_get_name(CFCClass *self) {
return self->name;
}
struct CFCDocuComment*
CFCClass_get_docucomment(CFCClass *self) {
return self->docucomment;
}