Explorar el Código

Fix problem submitting macros as queries.

- Previously it was only supported in legacy mode.  There isn't a good
  reason for that restriction.
- Simple macros and macros that didn't end in ';' might have had problems

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday hace 13 años
padre
commit
83c4afb368

+ 1 - 0
ecl/hql/hqlerrors.hpp

@@ -415,6 +415,7 @@
 #define HQLERR_CannotSubmitFunction 2385
 #define HQLERR_CannotSubmitModule   2386
 #define ERR_COUNTER_NOT_COUNT       2387
+#define HQLERR_CannotSubmitMacroX   2385
 
 #define ERR_ASSERTION_FAILS         100000
 

+ 21 - 4
ecl/hql/hqlutil.cpp

@@ -37,6 +37,7 @@
 #include "hqlattr.hpp"
 #include "hqlerror.hpp"
 #include "hqlexpr.ipp"
+#include "hqlrepository.hpp"
 
 #define SIZET_CACHE_SIZE    5001
 #define FIXEDATTR_CACHE_SIZE 1001
@@ -7343,22 +7344,38 @@ static IHqlExpression * transformAttributeToQuery(IHqlExpression * expr, HqlLook
 {
     if (expr->isMacro())
     {
-        if (!queryLegacyEclSemantics())
-            return NULL;
-        //Only expand macros if legacy semantics enabled
         IHqlExpression * macroBodyExpr;
         if (expr->getOperator() == no_funcdef)
         {
             if (expr->queryChild(1)->numChildren() != 0)
+            {
+                ctx.errs->reportError(HQLERR_CannotSubmitMacroX, "Cannot submit a MACRO with parameters()", NULL, 1, 0, 0);
                 return NULL;
+            }
             macroBodyExpr = expr->queryChild(0);
         }
         else
             macroBodyExpr = expr;
 
         IFileContents * macroContents = static_cast<IFileContents *>(macroBodyExpr->queryUnknownExtra());
+        size32_t len = macroContents->length();
+
+        //Strangely some macros still have the ENDMACRO on the end, and others don't.  This should be removed really.
+        StringBuffer macroText;
+        macroText.append(len, macroContents->getText());
+        if ((len >= 8) && strieq(macroText.str()+(len-8),"ENDMACRO"))
+            macroText.setLength(len-8);
+        //Now append a semi colon since that is how macros are normally called.
+        macroText.append(";");
+
+        //This might be cleaner if it was implemented by parsing the text myModule.myAttribute().
+        //It would make implementing default parameters easy.  However it could introduce other problems
+        //with implicitly importing myModule.
+        Owned<IFileContents> mappedContents = createFileContentsFromText(macroText.length(), macroText.str(), macroContents->querySourcePath());
         Owned<IHqlScope> scope = createPrivateScope();
-        return parseQuery(scope, macroContents, ctx, NULL, true);
+        if (queryLegacyEclSemantics())
+            importRootModulesToScope(scope, ctx);
+        return parseQuery(scope, mappedContents, ctx, NULL, true);
     }
 
     if (expr->isFunction())

+ 27 - 0
ecl/regress/macro12.eclxml

@@ -0,0 +1,27 @@
+<Archive>
+<!--
+
+    Copyright (C) 2011 HPCC Systems.
+
+    All rights reserved. This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+ <Module name="myModule">
+  <Attribute name="myAttr">
+      EXPORT myAttr := MACRO
+      'Hello world'
+      ENDMACRO;
+    </Attribute>
+  </Module>
+ <Query attributePath="myModule.myAttr"/>
+</Archive>

+ 27 - 0
ecl/regress/macro13.eclxml

@@ -0,0 +1,27 @@
+<Archive>
+<!--
+
+    Copyright (C) 2011 HPCC Systems.
+
+    All rights reserved. This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+ <Module name="myModule">
+  <Attribute name="myAttr">
+      EXPORT myAttr() := MACRO
+      'Hello world'
+      ENDMACRO;
+    </Attribute>
+  </Module>
+ <Query attributePath="myModule.myAttr"/>
+</Archive>

+ 28 - 0
ecl/regress/macro14.eclxml

@@ -0,0 +1,28 @@
+<Archive>
+<!--
+
+    Copyright (C) 2011 HPCC Systems.
+
+    All rights reserved. This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+ <Module name="myModule">
+  <Attribute name="myAttr">
+      //MACRO with parameters - even if the values are defaulted is not currently supported
+      EXPORT myAttr(name = 'unknown') := MACRO
+      'Hello world' + #TEXT(name)
+      ENDMACRO;
+    </Attribute>
+  </Module>
+ <Query attributePath="myModule.myAttr"/>
+</Archive>

+ 30 - 0
ecl/regress/macro15.eclxml

@@ -0,0 +1,30 @@
+<Archive>
+<!--
+
+    Copyright (C) 2011 HPCC Systems.
+
+    All rights reserved. This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+ <Module name="myModule">
+  <Attribute name="myAttr">
+  EXPORT myAttr() := MACRO
+      hello := 'hello';
+      sp := ' ';
+      world := 'world';
+      hello + sp + world
+  ENDMACRO;
+    </Attribute>
+  </Module>
+ <Query attributePath="myModule.myAttr"/>
+</Archive>

+ 36 - 0
ecl/regress/macro16.eclxml

@@ -0,0 +1,36 @@
+<Archive legacyMode="1">
+<!--
+
+    Copyright (C) 2011 HPCC Systems.
+
+    All rights reserved. This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+ <Module name="myModule">
+  <Attribute name="myAttr">
+  EXPORT myAttr() := MACRO
+      hello := 'hello';
+      sp := ' ';
+      world := 'world';
+      //Check that legacy mode means that modules are imported by default.
+      hello + sp + otherModule.myAttr
+  ENDMACRO;
+    </Attribute>
+  </Module>
+    <Module name="otherModule">
+        <Attribute name="myAttr">
+            EXPORT myAttr := 'world';
+        </Attribute>
+    </Module>
+    <Query attributePath="myModule.myAttr"/>
+</Archive>

+ 36 - 0
ecl/regress/macro17.eclxml

@@ -0,0 +1,36 @@
+<Archive legacyMode="1">
+<!--
+
+    Copyright (C) 2011 HPCC Systems.
+
+    All rights reserved. This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+ <Module name="myModule">
+  <Attribute name="myAttr">
+  EXPORT myAttr() := MACRO
+      hello := 'hello';
+      sp := ' ';
+      world := 'world';
+      //Check that legacy mode means that modules are imported by default.
+      hello + sp + otherModule.myAttr;
+  ENDMACRO;
+    </Attribute>
+  </Module>
+    <Module name="otherModule">
+        <Attribute name="myAttr">
+            EXPORT myAttr := 'world';
+        </Attribute>
+    </Module>
+    <Query attributePath="myModule.myAttr"/>
+</Archive>