Merge "Proceess post parse passes once for each type and expression"
diff --git a/AST.cpp b/AST.cpp
index ba3e250..7f24520 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -90,6 +90,20 @@
     err = validate();
     if (err != OK) return err;
 
+    // Make future packages not to call passes
+    // for processed types and expressions
+    constantExpressionRecursivePass([](ConstantExpression* ce) {
+        ce->setPostParseCompleted();
+        return OK;
+    });
+    std::unordered_set<const Type*> visited;
+    mRootScope.recursivePass(
+        [](Type* type) {
+            type->setPostParseCompleted();
+            return OK;
+        },
+        &visited);
+
     return OK;
 }
 
diff --git a/ConstantExpression.cpp b/ConstantExpression.cpp
index d4df274..b6a6824 100644
--- a/ConstantExpression.cpp
+++ b/ConstantExpression.cpp
@@ -440,6 +440,8 @@
 
 status_t ConstantExpression::recursivePass(const std::function<status_t(ConstantExpression*)>& func,
                                            std::unordered_set<const ConstantExpression*>* visited) {
+    if (mIsPostParseCompleted) return OK;
+
     if (visited->find(this) != visited->end()) return OK;
     visited->insert(this);
 
@@ -455,6 +457,11 @@
     return OK;
 }
 
+void ConstantExpression::setPostParseCompleted() {
+    CHECK(!mIsPostParseCompleted);
+    mIsPostParseCompleted = true;
+}
+
 std::vector<ConstantExpression*> LiteralConstantExpression::getConstantExpressions() const {
     return {};
 }
diff --git a/ConstantExpression.h b/ConstantExpression.h
index 5f8df93..ab17a4a 100644
--- a/ConstantExpression.h
+++ b/ConstantExpression.h
@@ -83,6 +83,10 @@
 
     size_t castSizeT() const;
 
+    // Marks that package proceeding is completed
+    // Post parse passes must be proceeded during owner package parsin
+    void setPostParseCompleted();
+
    private:
     /* If the result value has been evaluated. */
     bool mIsEvaluated = false;
@@ -95,6 +99,8 @@
     /* true if description() does not offer more information than value(). */
     bool mTrivialDescription = false;
 
+    bool mIsPostParseCompleted = false;
+
     /*
      * Helper function for all cpp/javaValue methods.
      * Returns a plain string (without any prefixes or suffixes, just the
diff --git a/Type.cpp b/Type.cpp
index bf48072..218848e 100644
--- a/Type.cpp
+++ b/Type.cpp
@@ -106,6 +106,8 @@
 
 status_t Type::recursivePass(const std::function<status_t(Type*)>& func,
                              std::unordered_set<const Type*>* visited) {
+    if (mIsPostParseCompleted) return OK;
+
     if (visited->find(this) != visited->end()) return OK;
     visited->insert(this);
 
@@ -127,6 +129,8 @@
 
 status_t Type::recursivePass(const std::function<status_t(const Type*)>& func,
                              std::unordered_set<const Type*>* visited) const {
+    if (mIsPostParseCompleted) return OK;
+
     if (visited->find(this) != visited->end()) return OK;
     visited->insert(this);
 
@@ -177,6 +181,11 @@
     return false;
 }
 
+void Type::setPostParseCompleted() {
+    CHECK(!mIsPostParseCompleted);
+    mIsPostParseCompleted = true;
+}
+
 std::string Type::getCppType(StorageMode, bool) const {
     CHECK(!"Should not be here");
     return std::string();
diff --git a/Type.h b/Type.h
index 3c2cbd3..2ef8201 100644
--- a/Type.h
+++ b/Type.h
@@ -87,6 +87,10 @@
     virtual bool isElidableType() const;
     virtual bool canCheckEquality() const;
 
+    // Marks that package proceeding is completed
+    // Post parse passes must be proceeded during owner package parsing
+    void setPostParseCompleted();
+
     enum StorageMode {
         StorageMode_Stack,
         StorageMode_Argument,
@@ -270,7 +274,9 @@
             const std::string &methodName,
             const std::string &name) const;
 
-private:
+   private:
+    bool mIsPostParseCompleted = false;
+
     DISALLOW_COPY_AND_ASSIGN(Type);
 };