Kaynağa Gözat

Refactor remote modules

This refactors the way remote scopes are processed in several ways
- Removes the way forward modules hold references to thier containing
  scope.  This removes an unnecessary (and incorrect) dependency.
- Split a parse context and lookup context to ensure the list required
  by the forward change is shared.
- Include whether out of line functions are expanded in the bound
  function cache to prevent mis-matching previous instances (and
  failing to fold)
- Removed legacy unused cluster assoicated with a repository

This is work on the way to better encapsulation and implemention of
modules in abstract source trees.

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 14 yıl önce
ebeveyn
işleme
f27fd7913e

+ 2 - 1
common/fileview2/fvtransform.cpp

@@ -287,7 +287,8 @@ void ViewTransformerRegistry::addPlugins(const char * name)
     ThrowingErrorReceiver errors;
     dataServer.setown(createSourceFileEclRepository(&errors, name, NULL, NULL, 0));
     HqlScopeArray scopes;
-    HqlLookupContext ctx(NULL, &errors, NULL, dataServer);
+    HqlParseContext parseCtx(dataServer, NULL);
+    HqlLookupContext ctx(parseCtx, &errors);
     dataServer->getRootScopes(scopes, ctx);
     ForEachItemIn(i, scopes)
     {

+ 63 - 60
ecl/eclcc/eclcc.cpp

@@ -666,7 +666,7 @@ static IHqlExpression * transformAttributeToQuery(EclCompileInstance & instance,
             macroBodyExpr = expr;
 
         IFileContents * macroContents = static_cast<IFileContents *>(macroBodyExpr->queryUnknownExtra());
-        Owned<IHqlRemoteScope> scope = createRemoteScope(NULL, NULL, ctx.eclRepository, NULL, NULL, false);
+        Owned<IHqlRemoteScope> scope = createRemoteScope(NULL, NULL, ctx.queryRepository(), NULL, NULL, false);
         return parseQuery(scope->queryScope(), macroContents, ctx, NULL, true);
     }
 
@@ -691,7 +691,7 @@ static IHqlExpression * transformAttributeToQuery(EclCompileInstance & instance,
             }
         }
 
-        return createBoundFunction(instance.errs, expr, actuals, ctx.functionCache, ctx.expandCallsWhenBound);
+        return createBoundFunction(instance.errs, expr, actuals, ctx.functionCache, ctx.queryExpandCallsWhenBound());
     }
 
     if (expr->isScope())
@@ -866,88 +866,91 @@ void EclCC::processSingleQuery(EclCompileInstance & instance, IEclRepository * d
     Owned<IHqlRemoteScope> rScope;
     Owned<IHqlScope> scope;
     Owned<ISourcePath> sourcePath = createSourcePath(sourcePathname);
-    if (!withinRepository && syntaxCheckModule)
-    {
-        if (!sourcePath)
-        {
-            StringBuffer temp;
-            temp.append(syntaxCheckModule).append('.').append(syntaxCheckAttribute);
-            sourcePath.setown(createSourcePath(temp));
-        }
-
-        scope.setown(createSyntaxCheckScope(*repository, syntaxCheckModule, syntaxCheckAttribute));
-        if (!scope)
-        {
-            StringBuffer msg;
-            msg.appendf("Module %s does not exist",syntaxCheckModule);
-            errs->reportError(0, msg.str(), sourcePath->str(), 1, 0, 0);
-            return;
-        }
-    }
-    else
-    {
-        rScope.setown(createRemoteScope(NULL, NULL, repository, NULL, NULL, false));
-        scope.set(rScope->queryScope());
-    }
-
-
     bool syntaxChecking = instance.wu->getDebugValueBool("syntaxCheck", false) || (syntaxCheckAttribute != NULL);
     size32_t prevErrs = errs->errCount();
     unsigned startTime = msTick();
     OwnedHqlExpr qquery;
     const char * defaultErrorPathname = sourcePathname ? sourcePathname : attributePath.str();
-    try
-    {
-        HqlExprArray functionCache;
-        HqlLookupContext ctx(instance.archive, errs, &functionCache, repository);
 
-        if (withinRepository)
+    {
+        //Minimize the scope of the parse context to reduce lifetime of cached items.
+        HqlParseContext parseCtx(repository, instance.archive);
+        if (!withinRepository && syntaxCheckModule)
         {
-            if (instance.archive)
+            if (!sourcePath)
             {
-                instance.archive->setProp("Query", "");
-                instance.archive->setProp("Query/@attributePath", attributePath);
+                StringBuffer temp;
+                temp.append(syntaxCheckModule).append('.').append(syntaxCheckAttribute);
+                sourcePath.setown(createSourcePath(temp));
             }
-            qquery.setown(getResolveAttributeFullPath(attributePath, LSFpublic, ctx));
-            if (!qquery && !syntaxChecking && (errs->errCount() == prevErrs))
+
+            scope.setown(createSyntaxCheckScope(parseCtx, syntaxCheckModule, syntaxCheckAttribute));
+            if (!scope)
             {
                 StringBuffer msg;
-                msg.append("Could not resolve attribute ").append(attributePath.str());
-                errs->reportError(3, msg.str(), defaultErrorPathname, 0, 0, 0);
+                msg.appendf("Module %s does not exist",syntaxCheckModule);
+                errs->reportError(0, msg.str(), sourcePath->str(), 1, 0, 0);
+                return;
             }
         }
         else
         {
-            Owned<IFileContents> contents = createFileContentsFromText(queryText, sourcePath);
+            rScope.setown(createRemoteScope(NULL, NULL, repository, NULL, NULL, false));
+            scope.set(rScope->queryScope());
+        }
+
+        try
+        {
+            HqlLookupContext ctx(parseCtx, errs);
 
-            if (instance.importAllModules)
+            if (withinRepository)
             {
-                HqlScopeArray rootScopes;
-                repository->getRootScopes(rootScopes, ctx);
-                ForEachItemIn(i, rootScopes)
+                if (instance.archive)
                 {
-                    IHqlScope & cur = rootScopes.item(i);
-                    scope->defineSymbol(cur.queryName(), NULL, LINK(queryExpression(&cur)), false, true, ob_module);
+                    instance.archive->setProp("Query", "");
+                    instance.archive->setProp("Query/@attributePath", attributePath);
+                }
+                qquery.setown(getResolveAttributeFullPath(attributePath, LSFpublic, ctx));
+                if (!qquery && !syntaxChecking && (errs->errCount() == prevErrs))
+                {
+                    StringBuffer msg;
+                    msg.append("Could not resolve attribute ").append(attributePath.str());
+                    errs->reportError(3, msg.str(), defaultErrorPathname, 0, 0, 0);
                 }
             }
+            else
+            {
+                Owned<IFileContents> contents = createFileContentsFromText(queryText, sourcePath);
 
-            qquery.setown(parseQuery(scope, contents, ctx, NULL, true));
-        }
+                if (instance.importAllModules)
+                {
+                    HqlScopeArray rootScopes;
+                    repository->getRootScopes(rootScopes, ctx);
+                    ForEachItemIn(i, rootScopes)
+                    {
+                        IHqlScope & cur = rootScopes.item(i);
+                        scope->defineSymbol(cur.queryName(), NULL, LINK(queryExpression(&cur)), false, true, ob_module);
+                    }
+                }
+
+                qquery.setown(parseQuery(scope, contents, ctx, NULL, true));
+            }
 
-        gatherWarnings(ctx.errs, qquery);
+            gatherWarnings(ctx.errs, qquery);
 
-        if (instance.wu->getDebugValueBool("addTimingToWorkunit", true))
-            instance.wu->setTimerInfo("EclServer: parse query", NULL, msTick()-startTime, 1, 0);
+            if (instance.wu->getDebugValueBool("addTimingToWorkunit", true))
+                instance.wu->setTimerInfo("EclServer: parse query", NULL, msTick()-startTime, 1, 0);
 
-        if (qquery && !syntaxChecking)
-            qquery.setown(convertAttributeToQuery(instance, qquery, ctx));
-    }
-    catch (IException *e)
-    {
-        StringBuffer s;
-        e->errorMessage(s);
-        errs->reportError(3, s.toCharArray(), defaultErrorPathname, 1, 0, 0);
-        e->Release();
+            if (qquery && !syntaxChecking)
+                qquery.setown(convertAttributeToQuery(instance, qquery, ctx));
+        }
+        catch (IException *e)
+        {
+            StringBuffer s;
+            e->errorMessage(s);
+            errs->reportError(3, s.toCharArray(), defaultErrorPathname, 1, 0, 0);
+            e->Release();
+        }
     }
 
     if (!syntaxChecking && (errs->errCount() == prevErrs) && (!qquery || !containsAnyActions(qquery)))

+ 1 - 1
ecl/hql/hqlesp.cpp

@@ -365,7 +365,7 @@ bool retrieveWebServicesInfo(IWorkUnit *workunit, HqlLookupContext & ctx)
     }
 
     //Names are currently stored case insensitively, we want the case sensitive variant.
-    OwnedHqlExpr s1 = ctx.eclRepository->lookupRootSymbol(createIdentifierAtom(moduleName.str()), LSFpublic, ctx);
+    OwnedHqlExpr s1 = ctx.queryRepository()->lookupRootSymbol(createIdentifierAtom(moduleName.str()), LSFpublic, ctx);
     if (s1 && s1->queryScope())
     {
         const char *caseSensitiveModuleName = s1->queryScope()->queryFullName();

+ 34 - 68
ecl/hql/hqlexpr.cpp

@@ -3764,11 +3764,12 @@ ITypeInfo *CHqlExpression::getType()
     return type;
 }
 
-IHqlExpression *CHqlExpression::addOperand(IHqlExpression *op)
+IHqlExpression *CHqlExpression::addOperand(IHqlExpression * child)
 {
-    assertex (!IsShared());
+    //Forward scopes are never commoned up, and are shared as a side-effect of keeping references to their owner
+    assertex (!IsShared() || (op == no_forwardscope));
     assertex (!isExprClosed());
-    doAppendOperand(*op);
+    doAppendOperand(*child);
     return this;
 }
 
@@ -5905,21 +5906,11 @@ ISourcePath * CHqlNamedSymbol::querySourcePath() const
     return CHqlAnnotation::querySourcePath();
 }
 
-CHqlCachedBoundFunction::CHqlCachedBoundFunction(IHqlExpression *func)
+CHqlCachedBoundFunction::CHqlCachedBoundFunction(IHqlExpression *func, bool _forceOutOfLineExpansion)
 : CHqlExpression(no_bound_func, NULL, LINK(func), NULL) 
 {
-}
-
-
-CHqlCachedBoundFunction::CHqlCachedBoundFunction(IHqlExpression *func, HqlExprArray &args)
-: CHqlExpression(no_bound_func, NULL, LINK(func), NULL) 
-{
-    ForEachItemIn(idx, args)
-    {
-        IHqlExpression &parm = (IHqlExpression &) args.item(idx);
-        parm.Link();
-        addOperand(& parm);
-    }
+    if (_forceOutOfLineExpansion)
+        addOperand(createConstant(true));
 }
 
 
@@ -6775,30 +6766,8 @@ static bool scopesEqual(const IHqlScope * l, const IHqlScope * r)
 
 //==============================================================================================================
 
-CHqlObservedScope::~CHqlObservedScope()
-{
-    cleanupForwardReferences();
-}
-
-
-void CHqlObservedScope::cleanupForwardReferences()
-{
-    CriticalBlock block(generalCS); // protect cachedItems
-    ForEachItemInRev(i, observedItems)
-        observedItems.item(i).cleanupForwardReferences();
-
-    assertex(observedItems.ordinality() == 0);
-}
-
-void CHqlObservedScope::invalidateParsed()
-{
-    cleanupForwardReferences();
-}
-
-//==============================================================================================================
-
 CHqlRemoteScope::CHqlRemoteScope(_ATOM _name, const char * _fullName, IEclRepository * _repository, IProperties* _props, IFileContents * _text, bool _lazy)
-: CHqlObservedScope(no_scope, _name, _fullName)
+: CHqlScope(no_scope, _name, _fullName)
 {
     op = no_remotescope;
     text.set(_text);
@@ -6939,12 +6908,12 @@ IHqlExpression *CHqlRemoteScope::lookupSymbol(_ATOM searchName, unsigned lookupF
     {
         if (resolvedSym)
         {
-            if (ctx.archive && resolvedSym->getOperator() == no_remotescope)
+            if (ctx.queryArchive() && resolvedSym->getOperator() == no_remotescope)
             {
                 //Ensure the archive contains entries for each module - even if nothing is accessed from it
                 //It would be preferrable to only check once, but adds very little time anyway.
                 IHqlScope * scope = resolvedSym->queryScope();
-                queryEnsureArchiveModule(ctx.archive, scope->queryFullName(), scope);
+                queryEnsureArchiveModule(ctx.queryArchive(), scope->queryFullName(), scope);
             }
 
             return resolvedSym.getClear();
@@ -7054,7 +7023,6 @@ void CHqlRemoteScope::getSymbols(HqlExprArray& exprs) const
 
 void CHqlRemoteScope::invalidateParsed()
 {
-    CHqlObservedScope::invalidateParsed();
     if (resolved)
     {
         CriticalBlock block(generalCS);
@@ -7805,22 +7773,21 @@ bool canBeVirtual(IHqlExpression * expr)
 
 //==============================================================================================================
 
-class CHqlForwardScope : public CHqlVirtualScope, public IHqlRemoteScopeObserver
+class CHqlForwardScope : public CHqlVirtualScope, public IHasUnlinkedOwnerReference
 {
 public:
-    CHqlForwardScope(IHqlRemoteScope * _remoteScope, HqlGramCtx * _parentCtx);
+    CHqlForwardScope(IHqlRemoteScope * _remoteScope, HqlGramCtx * _parentCtx, HqlParseContext & parseCtx);
     ~CHqlForwardScope()
     {
-        cleanupForwardReferences();
+        assertex(!remoteScope);
     }
     IMPLEMENT_IINTERFACE_USING(CHqlVirtualScope)
 
-    virtual void cleanupForwardReferences()
+    virtual void clearOwner()
     {
         if (remoteScope)
         {
             resolvedAll = true;
-            remoteScope->removeObserver(*this);
             parentCtx.clear();
             remoteScope = NULL;
         }
@@ -7831,22 +7798,20 @@ public:
     virtual IHqlScope * queryResolvedScope(HqlLookupContext * context);
 
 protected:
-    IHqlRemoteScope * remoteScope;
+    IHqlScope * remoteScope;
     Owned<HqlGramCtx> parentCtx;
     Owned<IHqlScope> resolved;
     bool resolvedAll;
 };
 
 //error if !fullBoundBase || isVirtual
-CHqlForwardScope::CHqlForwardScope(IHqlRemoteScope * _remoteScope, HqlGramCtx * _parentCtx) 
-: CHqlVirtualScope(NULL, NULL), remoteScope(_remoteScope), parentCtx(_parentCtx)
-{ 
+CHqlForwardScope::CHqlForwardScope(IHqlRemoteScope * _remoteScope, HqlGramCtx * _parentCtx, HqlParseContext & parseCtx)
+: CHqlVirtualScope(NULL, NULL), remoteScope(_remoteScope->queryScope()), parentCtx(_parentCtx)
+{
+    //Need to register this foward reference otherwise circular reference means it will never get deleted.
+    parseCtx.addForwardReference(remoteScope, this);
     op = no_forwardscope; 
     assertex(remoteScope);
-
-    //Need to register as an observer - otherwise circular reference means it will never get deleted.
-    remoteScope->addObserver(*this);
-
     //Until we've resolved the contents we have no idea if it is fully bound!
     if (parentCtx->hasAnyActiveParameters())
         infoFlags |= HEFunbound;
@@ -7915,7 +7880,7 @@ IHqlScope * CHqlForwardScope::queryResolvedScope(HqlLookupContext * context)
         //Generally we should have a lookup context passed in so the archive is updated correctly
         //But currently painful in one context, so allow it to be omitted.
         ThrowingErrorReceiver errors;
-        HqlLookupContext localCtx(NULL, &errors, NULL, NULL);
+        HqlDummyLookupContext localCtx(&errors);
         HqlLookupContext * activeContext = context ? context : &localCtx;
         HqlExprArray syms;
         getSymbols(syms);
@@ -8754,7 +8719,7 @@ IHqlExpression * CHqlAlienType::queryMemberFunc(_ATOM search)
 
 IHqlExpression *CHqlAlienType::lookupSymbol(_ATOM searchName)
 {
-    HqlLookupContext ctx(NULL, NULL, NULL, NULL);
+    HqlDummyLookupContext ctx(NULL);
     return scope->lookupSymbol(searchName, LSFpublic, ctx);
 }
 
@@ -9401,7 +9366,7 @@ protected:
                         newModule.setown(checkCreateConcreteModule(ctx.errors, newModule, newModule->queryProperty(_location_Atom)));
                     }
 
-                    HqlLookupContext dummyctx(NULL, ctx.errors, NULL, NULL);
+                    HqlDummyLookupContext dummyctx(ctx.errors);
                     return newModule->queryScope()->lookupSymbol(selectedName, makeLookupFlags(true, expr->hasProperty(ignoreBaseAtom), false), dummyctx);
                 }
                 break;
@@ -9753,7 +9718,7 @@ static IHqlExpression * cachedExpandFunctionCallBody(CallExpansionContext & ctx,
 {
     if (ctx.functionCache)
     {
-        CHqlCachedBoundFunction *cache2 = new CHqlCachedBoundFunction(call);
+        CHqlCachedBoundFunction *cache2 = new CHqlCachedBoundFunction(call, ctx.forceOutOfLineExpansion);
         Owned<CHqlCachedBoundFunction> cache = static_cast<CHqlCachedBoundFunction *>(cache2->closeExpr());
         if (cache->bound)
             return LINK(cache->bound);
@@ -11464,9 +11429,9 @@ extern IHqlScope* createVirtualScope()
     return new CHqlVirtualScope(NULL, NULL);
 }
 
-extern IHqlScope* createForwardScope(IHqlRemoteScope * remoteScope, HqlGramCtx * parentCtx)
+extern IHqlScope* createForwardScope(IHqlRemoteScope * remoteScope, HqlGramCtx * parentCtx, HqlParseContext & parseCtx)
 {
-    return new CHqlForwardScope(remoteScope, parentCtx);
+    return new CHqlForwardScope(remoteScope, parentCtx, parseCtx);
 }
 
 extern IHqlScope* createConcreteScope()
@@ -14658,18 +14623,18 @@ static void safeLookupSymbol(HqlLookupContext & ctx, IHqlScope * modScope, _ATOM
         HqlLookupContext localContext(ctx);
         StringBuffer xpath;
         xpath.append("Attr[@module=\"").append(moduleName).append("\"][@name=\"").append(name).append("\"]");
-        IPropertyTree * attr = localContext.dependTree->queryPropTree(xpath.str());
+        IPropertyTree * attr = localContext.queryDependTree()->queryPropTree(xpath.str());
         
         if (!attr)
         {
-            attr = localContext.dependTree->addPropTree("Attr", createPTree());
+            attr = localContext.queryDependTree()->addPropTree("Attr", createPTree());
             attr->setProp("@module", moduleName->str());
             attr->setProp("@name", name->str());
         }
         localContext.curAttrTree.set(attr);
 
         IFileContents * macroContents = static_cast<IFileContents *>(macroBodyExpr->queryUnknownExtra());
-        Owned<IHqlRemoteScope> scope = createRemoteScope(NULL, NULL, ctx.eclRepository, NULL, NULL, false);
+        Owned<IHqlRemoteScope> scope = createRemoteScope(NULL, NULL, ctx.queryRepository(), NULL, NULL, false);
         OwnedHqlExpr query = parseQuery(scope->queryScope(), macroContents, localContext, NULL, true);
         scope->invalidateParsed();
     }
@@ -14702,7 +14667,7 @@ static void gatherAttributeDependencies(HqlLookupContext & ctx, const char * ite
         else
             moduleName = createIdentifierAtom(item);
 
-        OwnedHqlExpr resolved = ctx.eclRepository->lookupRootSymbol(moduleName, LSFpublic, ctx);
+        OwnedHqlExpr resolved = ctx.queryRepository()->lookupRootSymbol(moduleName, LSFpublic, ctx);
         if (resolved)
         {
             IHqlScope * scope = resolved->queryScope();
@@ -14723,9 +14688,10 @@ static void gatherAttributeDependencies(HqlLookupContext & ctx, const char * ite
 
 extern HQL_API IPropertyTree * gatherAttributeDependencies(IEclRepository * dataServer, const char * items)
 {
-    HqlLookupContext ctx(NULL, NULL, NULL, dataServer);
-    ctx.dependTree.setown(createPTree("Dependencies"));
+    HqlParseContext parseCtx(dataServer, NULL);
+    parseCtx.dependTree.setown(createPTree("Dependencies"));
 
+    HqlLookupContext ctx(parseCtx, NULL);
     if (items && *items)
     {
         loop
@@ -14752,7 +14718,7 @@ extern HQL_API IPropertyTree * gatherAttributeDependencies(IEclRepository * data
         }
     }
 
-    return ctx.dependTree.getClear();
+    return parseCtx.dependTree.getClear();
 }
 
 

+ 69 - 31
ecl/hql/hqlexpr.hpp

@@ -840,46 +840,95 @@ public:
     virtual size32_t length() = 0;
 };
 
-class HqlLookupContext
+//This class ensures that the pointer to the owner is cleared before both links are released, which allows
+//you to safely have an unlinked owner pointer in a child while this class instance exists.
+template <class OWNER, class CHILD>
+class SafeOwnerReference : public CInterface
+{
+public:
+    inline SafeOwnerReference(OWNER * _owner, CHILD * _child) : owner(_owner), child(_child) {}
+    inline ~SafeOwnerReference() { child->clearOwner(); }
+protected:
+    Linked<OWNER> owner;
+    Linked<CHILD> child;
+};
+
+interface IHasUnlinkedOwnerReference : public IInterface
+{
+    virtual void clearOwner() = 0;
+};
+
+typedef SafeOwnerReference<IHqlScope, IHasUnlinkedOwnerReference> ForwardScopeItem;
+
+class HqlParseContext
 {
 public:
-    explicit HqlLookupContext(const HqlLookupContext & other)
+    HqlParseContext(IEclRepository * _eclRepository, IPropertyTree * _archive)
+    : archive(_archive), eclRepository(_eclRepository)
     {
-        set(other);
+        expandCallsWhenBound = DEFAULT_EXPAND_CALL;
     }
-    HqlLookupContext(IPropertyTree * _archive, IErrorReceiver * _errs, HqlExprArray * _functionCache, IEclRepository * _eclRepository) 
-    : archive(_archive), errs(_errs), eclRepository(_eclRepository)
-    { 
-        functionCache = _functionCache; 
-        expandCallsWhenBound = DEFAULT_EXPAND_CALL; 
+
+    inline IEclRepository * queryRepository() const { return eclRepository; }
+    void addForwardReference(IHqlScope * owner, IHasUnlinkedOwnerReference * child)
+    {
+        forwardLinks.append(*new ForwardScopeItem(owner, child));
     }
 
-    void set(const HqlLookupContext & other)    
+public:
+    Linked<IPropertyTree> archive;
+    Linked<IEclRepository> eclRepository;
+    Owned<IPropertyTree> dependTree;
+    HqlExprArray defaultFunctionCache;
+    CIArrayOf<ForwardScopeItem> forwardLinks;
+    bool expandCallsWhenBound;
+};
+
+class HqlDummyParseContext : public HqlParseContext
+{
+public:
+    HqlDummyParseContext() : HqlParseContext(NULL, NULL) {}
+};
+
+
+class HqlLookupContext
+{
+public:
+    explicit HqlLookupContext(const HqlLookupContext & other) : parseCtx(other.parseCtx)
     {
-        archive.set(other.archive);
         errs.set(other.errs); 
         functionCache = other.functionCache; 
-        dependTree.set(other.dependTree); 
         curAttrTree.set(other.curAttrTree); 
-        expandCallsWhenBound = other.expandCallsWhenBound;
-        eclRepository.set(other.eclRepository);
+    }
+    HqlLookupContext(HqlParseContext & _parseCtx, IErrorReceiver * _errs)
+    : parseCtx(_parseCtx), errs(_errs)
+    {
+        functionCache = &parseCtx.defaultFunctionCache;
     }
 
+    inline IPropertyTree * queryArchive() const { return parseCtx.archive; }
+    inline IPropertyTree * queryDependTree() const { return parseCtx.dependTree; }
+    inline IEclRepository * queryRepository() const { return parseCtx.eclRepository; }
+    inline bool queryExpandCallsWhenBound() const { return parseCtx.expandCallsWhenBound; }
+    inline HqlParseContext & queryParseContext() const { return parseCtx; }
+
+private:
+    HqlParseContext & parseCtx;
+
 public:
-    Linked<IPropertyTree> archive;
     Linked<IErrorReceiver> errs;
-    Linked<IEclRepository> eclRepository;
     HqlExprArray * functionCache;
-//  HqlExprArray defaultFunctionCache;  could assign by default, but slight concern about the lifetime
-    Owned<IPropertyTree> dependTree;
     Owned<IPropertyTree> curAttrTree;
-    bool expandCallsWhenBound;
 };
 
 class HqlDummyLookupContext : public HqlLookupContext
 {
 public:
-    HqlDummyLookupContext(IErrorReceiver * _errs) : HqlLookupContext(NULL, _errs, NULL, NULL) {}
+    //Potentially problematic - dummyCtx not created at the point the constructor is called.
+    HqlDummyLookupContext(IErrorReceiver * _errs) : HqlLookupContext(dummyCtx, _errs) {}
+
+private:
+    HqlDummyParseContext dummyCtx;
 };
 
 enum
@@ -924,15 +973,6 @@ interface IHqlScope : public IInterface
     virtual void removeSymbol(_ATOM name) = 0;      // use with great care
 };
 
-//Not pretty, but I haven't had any better ideas.
-//This interface allows child attributes to have temporary references to parent scopes, provided they are only present when parsing.
-//It is needed for forward module definitions becuase they need to preserve their context (so that the attributes can be evaluated late)
-//but will prevent the remote scope being destroyed unless something special is implemented....
-interface IHqlRemoteScopeObserver : public IInterface
-{
-    virtual void cleanupForwardReferences() =0;
-};
-
 interface IHqlRemoteScope : public IInterface
 {
     virtual IHqlScope * queryScope() = 0;
@@ -941,8 +981,6 @@ interface IHqlRemoteScope : public IInterface
     virtual void noteTextModified() = 0;
     virtual void addNestedScope(IHqlScope * childScope, unsigned flags) = 0;
     virtual void removeNestedScope(_ATOM name) = 0;
-    virtual void addObserver(IHqlRemoteScopeObserver & item) = 0;
-    virtual void removeObserver(IHqlRemoteScopeObserver & item) = 0;
     virtual bool isEmpty() const = 0;
     virtual void setText(IFileContents * query) = 0;
     virtual void setProp(_ATOM, const char *) = 0;
@@ -1266,7 +1304,7 @@ extern HQL_API IHqlScope *createService();
 extern HQL_API IHqlScope *createDatabase(IHqlExpression * name);
 extern HQL_API IHqlScope *createScope();
 extern HQL_API IHqlScope *createConcreteScope();
-extern HQL_API IHqlScope *createForwardScope(IHqlRemoteScope * remoteScope, HqlGramCtx * parentCtx);
+extern HQL_API IHqlScope *createForwardScope(IHqlRemoteScope * remoteScope, HqlGramCtx * parentCtx, HqlParseContext & parseCtx);
 extern HQL_API IHqlScope *createLibraryScope();
 extern HQL_API IHqlScope *createVirtualScope();
 extern HQL_API IHqlScope* createVirtualScope(_ATOM name, const char * fullName);

+ 6 - 26
ecl/hql/hqlexpr.ipp

@@ -898,35 +898,13 @@ public:
     virtual void deserialize(MemoryBuffer &) { UNIMPLEMENTED; }
 };
 
-class HQL_API CHqlObservedScope : public CHqlScope, implements IHqlRemoteScope
-{
-protected:
-    CriticalSection generalCS;
-    ICopyArrayOf<IHqlRemoteScopeObserver> observedItems;
-
-public:
-    CHqlObservedScope(node_operator _op, _ATOM _name, const char * _fullName) : CHqlScope(_op, _name, _fullName) {}
-    ~CHqlObservedScope();
-
-    IMPLEMENT_IINTERFACE_USING(CHqlScope)
-
-    virtual IHqlScope * queryScope()        { return this; }    // remove ambiguous call
-
-    virtual void invalidateParsed();
-
-    virtual void addObserver(IHqlRemoteScopeObserver & item) { observedItems.append(item); }
-    virtual void removeObserver(IHqlRemoteScopeObserver & item) { observedItems.zap(item); }
-
-protected:
-    void cleanupForwardReferences();
-};
-
-class HQL_API CHqlRemoteScope : public CHqlObservedScope
+class HQL_API CHqlRemoteScope : public CHqlScope, implements IHqlRemoteScope
 {
 protected:
     IEclRepository * ownerRepository;
     IProperties* props;
     Owned<IHqlScope> resolved;
+    CriticalSection generalCS;
     bool loadedAllSymbols;
 
 protected:
@@ -940,6 +918,9 @@ protected:
 public:
     CHqlRemoteScope(_ATOM _name, const char * _fullName, IEclRepository *_repository, IProperties* _props, IFileContents * _text, bool _lazy);
     ~CHqlRemoteScope();
+    IMPLEMENT_IINTERFACE_USING(CHqlScope)
+
+    virtual IHqlScope * queryScope()        { return this; }    // remove ambiguous call
 
 //interface IHqlExpression
     virtual IHqlExpression *clone(HqlExprArray &newkids);
@@ -1293,8 +1274,7 @@ class CHqlCachedBoundFunction : public CHqlExpression
 {
     friend class CHqlNamedSymbol;
 public:
-    CHqlCachedBoundFunction(IHqlExpression *func);
-    CHqlCachedBoundFunction(IHqlExpression *func, HqlExprArray &args);
+    CHqlCachedBoundFunction(IHqlExpression * func, bool _forceOutOfLineExpansion);
 
 public:
     LinkedHqlExpr bound;

+ 2 - 12
ecl/hql/hqlgram.hpp

@@ -350,25 +350,15 @@ typedef CIArrayOf<HqlExprArrayItem> HqlExprArrayArray;
 class HqlGramCtx : public CInterface
 {
 public:
-    HqlGramCtx() { lookupCtx = NULL; }
-    ~HqlGramCtx() { delete lookupCtx; }
+    HqlGramCtx(HqlLookupContext & _lookupCtx) : lookupCtx(_lookupCtx) {}
     bool hasAnyActiveParameters();
-    void cleanup()
-    {
-        defineScopes.kill();
-        defaultScopes.kill();
-        globalScope.clear();
-        imports.kill();
-        delete lookupCtx; 
-        lookupCtx = NULL;
-    }
 public:
     CIArrayOf<ActiveScopeInfo> defineScopes;
     IEclRepository *dataServer;
     HqlScopeArray defaultScopes;
     Owned<IHqlScope> globalScope;
     Linked<ISourcePath> sourcePath;
-    HqlLookupContext * lookupCtx;
+    HqlLookupContext lookupCtx;
     HqlExprArray imports;
 };
 

+ 21 - 22
ecl/hql/hqlgram2.cpp

@@ -276,7 +276,6 @@ HqlGram::HqlGram(IHqlScope * _containerScope, IFileContents * _text, HqlLookupCo
 {
     init(_containerScope, _containerScope);
     fieldMapUsed = _hasFieldMap;
-    lookupCtx.set(_ctx);
     if (!lookupCtx.functionCache)
         lookupCtx.functionCache = &localFunctionCache;
 
@@ -286,17 +285,17 @@ HqlGram::HqlGram(IHqlScope * _containerScope, IFileContents * _text, HqlLookupCo
     forceResult = false;
     lexObject = new HqlLex(this, _text, xmlScope, NULL);
 
-    if(lookupCtx.eclRepository && loadImplicit && legacyEclSemantics)
+    if(lookupCtx.queryRepository() && loadImplicit && legacyEclSemantics)
     {
         HqlScopeArray scopes;
-        getImplicitScopes(scopes, lookupCtx.eclRepository, _containerScope, lookupCtx);
+        getImplicitScopes(scopes, lookupCtx.queryRepository(), _containerScope, lookupCtx);
         ForEachItemIn(i, scopes)
             defaultScopes.append(OLINK(scopes.item(i)));
     }
 }
 
 HqlGram::HqlGram(HqlGramCtx & parent, IHqlScope * _containerScope, IFileContents * _text, IXmlScope *xmlScope)
-: lookupCtx(*parent.lookupCtx)
+: lookupCtx(parent.lookupCtx)
 {
     //This is used for parsing a constant expression inside the preprocessor
     //And reprocessing FORWARD module definitions.
@@ -342,7 +341,6 @@ void HqlGram::saveContext(HqlGramCtx & ctx, bool cloneScopes)
     ctx.globalScope.set(globalScope);
     appendArray(ctx.defaultScopes, defaultScopes);
     ctx.sourcePath.set(sourcePath);
-    ctx.lookupCtx = new HqlLookupContext(lookupCtx);
     parseScope->getSymbols(ctx.imports);
 };
 
@@ -2568,9 +2566,9 @@ void HqlGram::processForwardModuleDefinition(const attribute & errpos)
         return;
     }
 
-    HqlGramCtx * parentCtx = new HqlGramCtx;
+    HqlGramCtx * parentCtx = new HqlGramCtx(lookupCtx);
     saveContext(*parentCtx, true);
-    Owned<IHqlScope> newScope = createForwardScope(queryGlobalRemoteScope(), parentCtx);
+    Owned<IHqlScope> newScope = createForwardScope(queryGlobalRemoteScope(), parentCtx, lookupCtx.queryParseContext());
     IHqlExpression * newScopeExpr = queryExpression(newScope);
 
     ForEachChild(i, scopeExpr)
@@ -5780,8 +5778,9 @@ IHqlExpression *HqlGram::bindParameters(const attribute & errpos, IHqlExpression
     {
         try
         {
+            const bool expandCallsWhenBound = lookupCtx.queryExpandCallsWhenBound();
             if (function->getOperator() != no_funcdef)
-                return createBoundFunction(this, function, actuals, lookupCtx.functionCache, lookupCtx.expandCallsWhenBound);
+                return createBoundFunction(this, function, actuals, lookupCtx.functionCache, expandCallsWhenBound);
 
             IHqlExpression * body = function->queryChild(0);
             if (body->getOperator() == no_template_context)
@@ -5789,13 +5788,13 @@ IHqlExpression *HqlGram::bindParameters(const attribute & errpos, IHqlExpression
                 if (requireLateBind(function, actuals))
                 {
                     IHqlExpression * ret = NULL;
-                    if (!lookupCtx.expandCallsWhenBound)
+                    if (!expandCallsWhenBound)
                     {
                         HqlExprArray args;
                         args.append(*LINK(body));
                         unwindChildren(args, function, 1);
                         OwnedHqlExpr newFunction = createFunctionDefinition(function->queryName(), args);
-                        OwnedHqlExpr boundExpr = createBoundFunction(this, newFunction, actuals, lookupCtx.functionCache, lookupCtx.expandCallsWhenBound);
+                        OwnedHqlExpr boundExpr = createBoundFunction(this, newFunction, actuals, lookupCtx.functionCache, expandCallsWhenBound);
                         
                         // get rid of the wrapper
                         //assertex(boundExpr->getOperator()==no_template_context);
@@ -5803,7 +5802,7 @@ IHqlExpression *HqlGram::bindParameters(const attribute & errpos, IHqlExpression
                     }
                     else
                     {
-                        OwnedHqlExpr boundExpr = createBoundFunction(this, function, actuals, lookupCtx.functionCache, lookupCtx.expandCallsWhenBound);
+                        OwnedHqlExpr boundExpr = createBoundFunction(this, function, actuals, lookupCtx.functionCache, expandCallsWhenBound);
                         
                         // get rid of the wrapper
                         assertex(boundExpr->getOperator()==no_template_context);
@@ -5830,7 +5829,7 @@ IHqlExpression *HqlGram::bindParameters(const attribute & errpos, IHqlExpression
             }
             else
             {
-                bool expandCall = insideTemplateFunction() ? false : lookupCtx.expandCallsWhenBound;
+                bool expandCall = insideTemplateFunction() ? false : expandCallsWhenBound;
                 // do the actual binding
                 return createBoundFunction(this, function, actuals, lookupCtx.functionCache, expandCall);
             }
@@ -9339,7 +9338,7 @@ IHqlExpression * HqlGram::createEvaluateOutputModule(const attribute & errpos, I
 {
     if (!ifaceExpr->queryType()->assignableFrom(scopeExpr->queryType()))
         reportError(ERR_NOT_BASE_MODULE, errpos, "Module doesn't implement the interface supplied");
-    return ::createEvaluateOutputModule(lookupCtx, scopeExpr, ifaceExpr, lookupCtx.expandCallsWhenBound, outputOp);
+    return ::createEvaluateOutputModule(lookupCtx, scopeExpr, ifaceExpr, lookupCtx.queryExpandCallsWhenBound(), outputOp);
 }
 
 IHqlExpression * HqlGram::createStoredModule(const attribute & errpos, IHqlExpression * scopeExpr)
@@ -9543,7 +9542,7 @@ IHqlScope * HqlGram::resolveImportModule(const attribute & errpos, IHqlExpressio
         return LINK(globalScope);
     if (name != _dot_Atom)
     {
-        if (!lookupCtx.eclRepository)
+        if (!lookupCtx.queryRepository())
         {
             //This never happens in practice since a null repository is generally passed.
             reportError(ERR_MODULE_UNKNOWN, "Import not supported with no repository specified",  
@@ -9553,7 +9552,7 @@ IHqlScope * HqlGram::resolveImportModule(const attribute & errpos, IHqlExpressio
             return NULL;
         }
 
-        OwnedHqlExpr importMatch = lookupCtx.eclRepository->lookupRootSymbol(name, LSFimport, lookupCtx);
+        OwnedHqlExpr importMatch = lookupCtx.queryRepository()->lookupRootSymbol(name, LSFimport, lookupCtx);
         if (!importMatch)
             importMatch.setown(parseScope->lookupSymbol(name, LSFsharedOK, lookupCtx));
 
@@ -11021,9 +11020,9 @@ extern HQL_API IHqlExpression * parseQuery(IHqlScope *scope, IFileContents * con
     {
         if (scope && scope->queryName())
         {
-            if (ctx.archive)
+            if (ctx.queryArchive())
             {
-                IPropertyTree * module = queryEnsureArchiveModule(ctx.archive, scope->queryFullName(), scope);
+                IPropertyTree * module = queryEnsureArchiveModule(ctx.queryArchive(), scope->queryFullName(), scope);
 
                 StringBuffer sillyTempBuffer;
                 sillyTempBuffer.append(contents->length(), contents->getText());
@@ -11064,7 +11063,7 @@ extern HQL_API IHqlExpression * parseQuery(IHqlScope *scope, IFileContents * con
 extern HQL_API IHqlExpression * parseQuery(const char * text, IErrorReceiver * errs)
 {
     Owned<IHqlScope> scope = createScope();
-    HqlLookupContext ctx(NULL, errs, NULL, NULL);
+    HqlDummyLookupContext ctx(errs);
     Owned<IFileContents> contents = createFileContentsFromText(text, NULL);
     return parseQuery(scope, contents, ctx, NULL, true);
 }
@@ -11087,9 +11086,9 @@ bool parseForwardModuleMember(HqlGramCtx & _parent, IHqlScope *scope, IHqlExpres
 void parseAttribute(IHqlScope * scope, IFileContents * contents, HqlLookupContext & ctx, _ATOM name)
 {
     const char * moduleName = scope->queryFullName();
-    if (ctx.archive != NULL)
+    if (ctx.queryArchive())
     {
-        IPropertyTree * module = queryEnsureArchiveModule(ctx.archive, moduleName, scope);
+        IPropertyTree * module = queryEnsureArchiveModule(ctx.queryArchive(), moduleName, scope);
         IPropertyTree * attr = queryArchiveAttribute(module, name->str());
         if (!attr)
             attr = createArchiveAttribute(module, name->str());
@@ -11103,9 +11102,9 @@ void parseAttribute(IHqlScope * scope, IFileContents * contents, HqlLookupContex
     }
 
     HqlLookupContext attrCtx(ctx);
-    if (attrCtx.dependTree)
+    if (attrCtx.queryDependTree())
     {
-        IPropertyTree * attr = attrCtx.dependTree->addPropTree("Attr", createPTree());
+        IPropertyTree * attr = attrCtx.queryDependTree()->addPropTree("Attr", createPTree());
         attrCtx.curAttrTree.set(attr);
         attr->setProp("@module", scope->queryName()->str());
         attr->setProp("@name", name->str());

+ 4 - 4
ecl/hql/hqlparse.cpp

@@ -92,7 +92,7 @@ public:
        m_startLine(startLine), m_startCol(startCol) {}
     
     virtual IXmlScope* queryXmlScope()  { return m_xmlScope; }
-    virtual IEclRepository* queryDataServer()  { return m_lookupContext.eclRepository; }
+    virtual IEclRepository* queryDataServer()  { return m_lookupContext.queryRepository(); }
     
     // convenient functions
     virtual bool isInModule(const char* moduleName, const char* attrName) { return ::isInModule(m_lookupContext, moduleName,attrName); }
@@ -1314,7 +1314,7 @@ void HqlLex::doInModule(YYSTYPE & returnToken)
 
 static bool isInModule(HqlLookupContext & ctx, const char* moduleName, const char* attrName)
 {
-    if (!ctx.eclRepository)
+    if (!ctx.queryRepository())
         return false;
 
     try
@@ -1326,7 +1326,7 @@ static bool isInModule(HqlLookupContext & ctx, const char* moduleName, const cha
         const char* pAttr = attrName;
         while(*pAttr==' ') pAttr++;
 
-        OwnedHqlExpr match = ctx.eclRepository->lookupRootSymbol(createIdentifierAtom(pModule), LSFpublic, ctx);
+        OwnedHqlExpr match = ctx.queryRepository()->lookupRootSymbol(createIdentifierAtom(pModule), LSFpublic, ctx);
         IHqlScope * scope = match ? match->queryScope() : NULL;
         if (scope)
         {
@@ -1705,7 +1705,7 @@ IHqlExpression *HqlLex::parseECL(StringBuffer &curParam, IXmlScope *xmlScope, in
     Owned<IHqlScope> scope = new CHqlMultiParentScope(sharedAtom,yyParser->queryPrimaryScope(false),yyParser->queryPrimaryScope(true),yyParser->parseScope.get(),NULL); 
 //  scope->defineSymbol(yyParser->globalScope->queryName(), NULL, LINK(queryExpression(yyParser->globalScope)), false, false, ob_module);
 
-    HqlGramCtx parentContext;
+    HqlGramCtx parentContext(yyParser->lookupCtx);
     yyParser->saveContext(parentContext, false);
     Owned<IFileContents> contents = createFileContentsFromText(curParam, querySourcePath());
     HqlGram parser(parentContext, scope, contents, xmlScope); 

+ 4 - 2
ecl/hql/hqlplugininfo.cpp

@@ -39,7 +39,8 @@ IEclRepository * loadPlugins(const char * pluginPath, const char * libraryPath,
 
 IPropertyTree * createPluginPropertyTree(IEclRepository * plugins, bool includeModuleText)
 {
-    HqlLookupContext ctx(NULL, NULL, NULL, plugins);
+    HqlParseContext parseCtx(plugins, NULL);
+    HqlLookupContext ctx(parseCtx, NULL);
     HqlScopeArray scopes;
     plugins->getRootScopes(scopes, ctx);
 
@@ -100,7 +101,8 @@ IPropertyTree * getPlugin(IPropertyTree * p, IEclRepository * plugins, const cha
 
     if(load && !plugin->getPropInt("@loaded",0))
     {
-        HqlLookupContext GHMOREctx(NULL, NULL,  NULL, plugins);
+        HqlParseContext parseCtx(plugins, NULL);
+        HqlLookupContext GHMOREctx(parseCtx, NULL);
         Owned<IHqlScope> resolved = getResolveDottedScope(modname, LSFpublic, GHMOREctx);
         if (resolved)
             exportSymbols(plugin, resolved, GHMOREctx);

+ 10 - 23
ecl/hql/hqlremote.cpp

@@ -309,11 +309,9 @@ class RemoteXmlEclRepository : public XmlEclRepository
     timestamp_t cachestamp;
 
 public:
-    RemoteXmlEclRepository(IEclUser * _user, IXmlEclRepository &repository, const char* cluster, const char * _snapshot, bool _sandbox4snapshot);
+    RemoteXmlEclRepository(IEclUser * _user, IXmlEclRepository &repository, const char * _snapshot, bool _sandbox4snapshot);
     ~RemoteXmlEclRepository();
 
-    void shutdown();
-    void getActiveUsers(char *&ret);
     void logException(IException *e);
 
 //interface readDataServer
@@ -325,16 +323,13 @@ public:
     virtual IPropertyTree* getAttributes(const char *module, const char *attr, int version, unsigned char infoLevel); 
 
     virtual bool logging() { return true; }
-
-protected:
-    void setCurrentCluster(const char* cluster);
 };
 
 
 
 //==============================================================================================================
 
-RemoteXmlEclRepository::RemoteXmlEclRepository(IEclUser * _user, IXmlEclRepository &_repository, const char* _cluster, const char * _snapshot, bool _sandbox4snapshot) 
+RemoteXmlEclRepository::RemoteXmlEclRepository(IEclUser * _user, IXmlEclRepository &_repository, const char * _snapshot, bool _sandbox4snapshot)
 : repository(_repository), user(_user)
 {
     if (_snapshot && *_snapshot)
@@ -343,8 +338,6 @@ RemoteXmlEclRepository::RemoteXmlEclRepository(IEclUser * _user, IXmlEclReposito
         setPropInt("sandbox4snapshot", _sandbox4snapshot ? 1 : 0);
     }
     cachestamp = 0;
-
-    setCurrentCluster(_cluster);
 }
 
 RemoteXmlEclRepository::~RemoteXmlEclRepository()
@@ -475,21 +468,16 @@ IPropertyTree* RemoteXmlEclRepository::getAttributes(const char *module, const c
 }
 
 
-void RemoteXmlEclRepository::setCurrentCluster(const char* _cluster)
-{
-    setProp("cluster",_cluster);
-}
-
-extern "C" HQL_API IEclRepository * attachLocalServer(IEclUser * user, IXmlEclRepository & repository, const char* cluster, const char * snapshot, bool sandbox4snapshot)
+extern "C" HQL_API IEclRepository * attachLocalServer(IEclUser * user, IXmlEclRepository & repository, const char * snapshot, bool sandbox4snapshot)
 {
-    return new RemoteXmlEclRepository(user, repository, cluster, snapshot, sandbox4snapshot);
+    return new RemoteXmlEclRepository(user, repository, snapshot, sandbox4snapshot);
 }
 
 class LoggingDataServer: public RemoteXmlEclRepository
 {
 public:
-    LoggingDataServer(IEclUser * user, IXmlEclRepository & repository, const char* cluster, IWorkUnit* _workunit, const char * snapshot, bool _sandbox4snapshot):
-      RemoteXmlEclRepository(user, repository, cluster, snapshot, _sandbox4snapshot),
+    LoggingDataServer(IEclUser * user, IXmlEclRepository & repository, IWorkUnit* _workunit, const char * snapshot, bool _sandbox4snapshot):
+      RemoteXmlEclRepository(user, repository, snapshot, _sandbox4snapshot),
       workunit(_workunit)
     {
           setPropInt("preloadText",0);
@@ -570,9 +558,7 @@ public:
 
 extern "C" HQL_API IEclRepository * attachLoggingServer(IEclUser * user, IXmlEclRepository & repository, IWorkUnit* workunit, const char * snapshot, bool sandbox4snapshot)
 {
-    SCMStringBuffer cluster;
-    workunit->getClusterName(cluster);
-    return new LoggingDataServer(user, repository, cluster.str(), workunit, snapshot, sandbox4snapshot);
+    return new LoggingDataServer(user, repository, workunit, snapshot, sandbox4snapshot);
 }
 
 
@@ -646,7 +632,8 @@ bool ArchiveXmlEclRepository::loadModule(IHqlRemoteScope *rScope, IErrorReceiver
 
 void ArchiveXmlEclRepository::init()
 {
-    HqlLookupContext GHMOREctx(NULL, NULL,  NULL, defaultDataServer);
+    HqlParseContext parseCtx(defaultDataServer, NULL);
+    HqlLookupContext ctx(parseCtx, NULL);
     Owned<IPropertyTreeIterator> modit = repository->getElements("Module");
     ForEach(*modit)
     {
@@ -657,7 +644,7 @@ void ArchiveXmlEclRepository::init()
         if (defaultDataServer)
         {
             _ATOM name = createIdentifierAtom(modname);
-            OwnedHqlExpr match = defaultDataServer->lookupRootSymbol(name, LSFpublic, GHMOREctx);
+            OwnedHqlExpr match = defaultDataServer->lookupRootSymbol(name, LSFpublic, ctx);
             IHqlScope * defaultScope = match ? match->queryScope() : NULL;
             if (defaultScope && (defaultScope->getPropInt(flagsAtom, 0) & SOURCEFILE_PLUGIN))
             {

+ 1 - 1
ecl/hql/hqlremote.hpp

@@ -49,7 +49,7 @@ public:
 
 
 extern HQL_API IXmlEclRepository * createReplayRepository(IPropertyTree * xml);
-extern "C" HQL_API IEclRepository * attachLocalServer(IEclUser * user, IXmlEclRepository & repository, const char* cluster, const char * snapshot, bool sandbox4snapshot);
+extern "C" HQL_API IEclRepository * attachLocalServer(IEclUser * user, IXmlEclRepository & repository, const char * snapshot, bool sandbox4snapshot);
 extern "C" HQL_API IEclRepository * attachLoggingServer(IEclUser * user, IXmlEclRepository & repository, IWorkUnit* workunit, const char * snapshot, bool sandbox4snapshot);
 extern "C" HQL_API IEclRepository * createXmlDataServer(IPropertyTree * _xml, IEclRepository * defaultDataServer);
 

+ 7 - 7
ecl/hql/hqlrepository.cpp

@@ -76,7 +76,7 @@ IHqlExpression * getResolveAttributeFullPath(const char * attrname, unsigned loo
         }
         else
         {
-            resolved.setown(ctx.eclRepository->lookupRootSymbol(moduleName, lookupFlags, ctx));
+            resolved.setown(ctx.queryRepository()->lookupRootSymbol(moduleName, lookupFlags, ctx));
         }
 
         if (!resolved || !dot)
@@ -101,17 +101,18 @@ IHqlScope * getResolveDottedScope(const char * modname, unsigned lookupFlags, Hq
 }
 
 
-IHqlScope * createSyntaxCheckScope(IEclRepository & repository, const char * module, const char *attributes)
+IHqlScope * createSyntaxCheckScope(HqlParseContext & parseCtx, const char * module, const char *attributes)
 {
     //MORE: This doesn't currently work on child modules, and the list of attributes is overkill - a single item would be enough.
-    repository.checkCacheValid();
+    parseCtx.queryRepository()->checkCacheValid();
+
     //GHMORE: This whole function should really die.
-    HqlLookupContext GHMOREctx(NULL, NULL,  NULL, &repository);
-    Owned<IHqlScope> parent = getResolveDottedScope(module, LSFimport, GHMOREctx);
+    HqlLookupContext lookupCtx(parseCtx, NULL);
+    Owned<IHqlScope> parent = getResolveDottedScope(module, LSFimport, lookupCtx);
     if (!parent)
         return NULL;
 
-    return new CHqlSyntaxCheckScope(parent, &repository, attributes, true);
+    return new CHqlSyntaxCheckScope(parent, parseCtx.queryRepository(), attributes, true);
 }
 
 //-------------------------------------------------------------------------------------------------------------------
@@ -507,4 +508,3 @@ extern void getImplicitScopes(HqlScopeArray& implicitScopes, IEclRepository * re
             implicitScopes.append(OLINK(scope));
     }
 }
-

+ 3 - 1
ecl/hql/hqlrepository.hpp

@@ -141,11 +141,13 @@ private:
     unsigned traceMask;
 };
 
+class HqlParseContext;
+
 extern HQL_API IEclRepository *createSourceFileEclRepository(IErrorReceiver *err, const char * pluginPath, const char * constSourceSearchPath, const char * dynamicSourceSearchPath, unsigned traceMask);
 extern HQL_API IErrorReceiver *createFileErrorReceiver(FILE *f);
 extern HQL_API IHqlScope * getResolveDottedScope(const char * modname, unsigned lookupFlags, HqlLookupContext & ctx);
 extern HQL_API IHqlExpression * getResolveAttributeFullPath(const char * attrname, unsigned lookupFlags, HqlLookupContext & ctx);
-extern HQL_API IHqlScope * createSyntaxCheckScope(IEclRepository & repository, const char * module, const char *attributes);
+extern HQL_API IHqlScope * createSyntaxCheckScope(HqlParseContext & parseCtx, const char * module, const char *attributes);
 extern HQL_API IEclRepository * createCompoundRepositoryF(IEclRepository * repository, ...);
 extern HQL_API void getImplicitScopes(HqlScopeArray & implicitScopes, IEclRepository * repository, IHqlScope * scope, HqlLookupContext & ctx);
 

+ 1 - 1
ecl/hql/hqlutil.cpp

@@ -5516,7 +5516,7 @@ void LibraryInputMapper::mapLogicalToReal(HqlExprArray & mapped, IHqlExpression
         HqlExprArray symbols;
         scope->getSymbols(symbols);
 
-        HqlLookupContext lookupCtx(NULL, NULL, NULL, NULL);
+        HqlDummyLookupContext lookupCtx(NULL);
         ForEachItemIn(i, symbols)
         {
             IHqlExpression & cur = symbols.item(i);