Skip to content

Commit

Permalink
add type registery (and register constructor and interface)
Browse files Browse the repository at this point in the history
  • Loading branch information
Constellation committed Aug 31, 2011
1 parent 0071ce9 commit 6612b46
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 1 deletion.
11 changes: 11 additions & 0 deletions az/cfa2/binding_resolver.h
@@ -1,4 +1,6 @@
// resolve which identifier is STACK or HEAP
//
// and collect @constructor / @interface jsdoc information
#ifndef AZ_CFA2_BINDING_RESOLVER_H_
#define AZ_CFA2_BINDING_RESOLVER_H_
#include <functional>
Expand Down Expand Up @@ -314,6 +316,15 @@ void BindingResolver::Visit(ExpressionStatement* stmt) {
void BindingResolver::Visit(Assignment* assign) {
assign->left()->Accept(this);
assign->right()->Accept(this);
if (FunctionLiteral* literal = assign->right()->AsFunctionLiteral()) {
if (std::shared_ptr<jsdoc::Info> info = heap_->GetInfo(assign)) {
if (info->GetTag(jsdoc::Token::TK_CONSTRUCTOR)) {
heap_->RegisterAssignedType(assign->left(), literal);
} else if (info->GetTag(jsdoc::Token::TK_INTERFACE)) {
heap_->RegisterAssignedType(assign->right(), literal);
}
}
}
}

void BindingResolver::Visit(BinaryOperation* binary) {
Expand Down
36 changes: 36 additions & 0 deletions az/cfa2/debug_completer.h
@@ -0,0 +1,36 @@
#ifndef AZ_CFA2_DEBUG_COMPLETER_H_
#define AZ_CFA2_DEBUG_COMPLETER_H_
#include <az/ast_fwd.h>
#include <az/cfa2/completer.h>
namespace az {
namespace cfa2 {

class DebugCompleter : public Completer {
public:
typedef std::unordered_map<Symbol, AVal> Properties;

DebugCompleter()
: Completer(),
properties_() {
}

void Output() const {
assert(heap());
}


void Notify(Symbol name, const AVal& target) {
if (properties_.find(name) == properties_.end()) {
properties_.insert(std::make_pair(name, target));
} else {
properties_[name].Join(target);
}
}

private:
Heap* heap_;
Properties properties_;
};

} } // namespace az::cfa2
#endif // AZ_CFA2_DEBUG_COMPLETER_H_
10 changes: 9 additions & 1 deletion az/cfa2/heap.h
Expand Up @@ -13,6 +13,7 @@
#include <az/cfa2/summary.h>
#include <az/cfa2/state.h>
#include <az/cfa2/result.h>
#include <az/cfa2/type_registry.h>
namespace az {
namespace cfa2 {

Expand All @@ -37,7 +38,8 @@ class Heap : public az::Context {
not_reachable_functions_(),
method_and_target_(),
target_cache_(),
object_literal_member_() {
object_literal_member_(),
registry_() {
}

// lazy initialization
Expand Down Expand Up @@ -1182,6 +1184,11 @@ class Heap : public az::Context {
return number_object_;
}

// type registry
void RegisterAssignedType(Expression* name, FunctionLiteral* literal) {
registry_.RegisterAssignedType(name, literal);
}

private:
HeapSet heap_;
HeapSet declared_heap_bindings_;
Expand Down Expand Up @@ -1222,6 +1229,7 @@ class Heap : public az::Context {
std::unordered_map<FunctionLiteral*, Expression*> method_and_target_;
std::unordered_map<Expression*, AVal> target_cache_;
std::unordered_map<FunctionLiteral*, AObject*> object_literal_member_;
TypeRegistry registry_;
};

} } // namespace az::cfa2
Expand Down
48 changes: 48 additions & 0 deletions az/cfa2/type_registry.h
@@ -1,9 +1,57 @@
#ifndef AZ_CFA2_TYPE_REGISTRY_H_
#define AZ_CFA2_TYPE_REGISTRY_H_
#include <az/debug_log.h>
#include <az/ast_fwd.h>
namespace az {
namespace cfa2 {

class TypeRegistry {
public:
TypeRegistry()
: map_() {
}

void RegisterAssignedType(Expression* lhs, FunctionLiteral* literal) {
iv::core::UString name;
assert(lhs->IsValidLeftHandSide());
// if FunctionLiteral name found, use this
if (iv::core::Maybe<Identifier> i = literal->name()) {
Identifier* ident = i.Address();
name.assign(ident->value().begin(), ident->value().end());
map_.insert(std::make_pair(name, literal));
} else {
// get name from Assignment
if (TypeRegistry::NormalizeName(lhs, &name)) {
DebugLog(name);
map_.insert(std::make_pair(name, literal));
}
}
}

private:
static bool NormalizeName(Expression* lhs, iv::core::UString* name) {
// TODO:(Constellation) fix it more efficiently
std::vector<uint16_t> reversed;
Expression* current = lhs;
while (true) {
if (Identifier* ident = current->AsIdentifier()) {
name->append(ident->value().begin(), ident->value().end());
name->insert(name->end(), reversed.rbegin(), reversed.rend());
return true;
} else if (IdentifierAccess* access = current->AsIdentifierAccess()) {
Identifier* prop = access->key();
reversed.insert(reversed.end(),
prop->value().rbegin(), prop->value().rend());
reversed.push_back('.');
current = access->target();
} else {
return false;
}
}
return true; // make compiler happy
}

std::unordered_map<iv::core::UString, FunctionLiteral*> map_;
};

} } // namespace az::cfa2
Expand Down

0 comments on commit 6612b46

Please sign in to comment.