Paul, > On 19 May 2020, at 7:21, Paul King <pa...@asert.com.au> wrote: > Groovy is all geared up to make it easy for you to do whatever pre-processing > you might like as an AST transform
Well of course, but the preprocessor is already done (actually predates our usage of Groovy and was just somewhat upgraded to work with it instead of Java sources), and it's questionable whether the effort needed to completely re-write its functionality into ASTT would be worth it. Aside of that... > and in that scenario it automatically corrects line numbering as needed (your > AST transform may have to play its part in making that work). ... I do not really know how to do that, either. I actually did try; let's say, I've got something like (non-essential parts removed, it would not quite work this way, just to show the concept): === @GroovyASTTransformation(phase = CompilePhase.INITIALIZATION) class PreprocessorAST extends ASTT { void visitNodes(ASTNode[] nodes, SourceUnit su) { cc.pluginFactory=PreprocessorFactory.newInstance() } } class PreprocessorFactory extends ParserPluginFactory { ParserPlugin createParserPlugin() { PreprocessorPlugin.newInstance() } } class PreprocessorPlugin extends AntlrParserPlugin { Reduction parseCST(SourceUnit su, Reader reader) { def nrdr=StringReader.newInstance(preprocessSource(reader.text,su.name)) super.parseCST(su,nrdr) } String preprocessSource(String text,String srcpath) { StringBuffer sb=StringBuffer.newInstance() text.eachLine { line -> ... whatever needed to pre-process the source ... sb.append(... the result, which can be 'line' or can differ ...) } sb.toString() } } === I haven't been able any reasonable way to submit the proper file names and line numbers to the further processing anyway. Let's assume the preprocessSource service finds another file, foo.h, should be included. I could easily read its contents and put it into the string buffer sb, so far so good — but how do I let the subsequent stages of the compilation know the changed lines actually should refer foo.h with appropriate line numbers? Whatever I tried, I found no API for that. The preprocessing did not work well, for the subsequent stages of compilation did refer to the original file (the one referenced by the source unit su), and changes in its content confused it mightily. > So, in that scenario you'd move whatever you do in CPP land into Groovy. The > advantage of this approach is that if you ever used things like coverage > tools etc., they would also be showing correct info and wouldn't become one > more place to fix. That's precisely why I asked whether there's a reliable way to fix the file names and line numbers in an ASTT so that they refer properly to the original sources. > If doing everything as an AST really can't be done, you can change just the > line number info in an AST transform but it could be a little brittle. I am > not 100% sure, but my suspicion is that if you only changed part of the line > numbering info and some of that info was now out of order with line info in > other places which you didn't touch, there could be problems. And then some :) Been there, done that, returned to the external fixes, leaving the preprocessed-file name and linenumbers in generated .classes. Thanks and all the best, OC > On Tue, May 19, 2020 at 12:19 PM OCsite <o...@ocs.cz <mailto:o...@ocs.cz>> > wrote: > There's another thing I'd like to ask for a help with. > > Some of my groovy sources are actually pre-processed (in a way remotely > similar to the well-known CPP, i.e., before groovyc is called, a temporary > groovy source is generated from one or more original sources; it's the > generated temp file which then gets compiled by groovyc and is turned to an > appropriate .class). > > Currently, I am fixing the file names and source line numbers externally, > i.e., I am > (a) catching the issues the compiler reports, and re-write the file name and > line number as needed before sending it up to Xcode to show them in its issue > list; > (b) before displaying a stack trace in my code, I am fixing the file names > and line numbers similarly, based on the information from the preprocessor, > which I store as a resource in my application JAR. > > That does work, but is a bit at the complex, error-prone and ugly side. > > I wonder: couldn't I write an ASTT which would fix the file names and line > numbers directly in the compiled .class, so that all the reported issues from > the compiler, just as all the runtime thrown exceptions etc., would not need > to be fixed anymore, for that would all properly address the original sources > and their line numbers? > > I have actually tried to do that at the CompilePhase.INITIALIZATION time, > with no real success. It does not seem I am able to change the source files > node-based, only a SourceUnit seems to allow that — whilst a pre-processed > file actually contains result of more different original source files, oops. > What's even worse, whilst I can override configureAST in my own ParserPlugin > subclass to fix the line numbers there (haven't found any other place to do > that), it fails in a number of ways even in the simplest case of a > pre-processed file containing result of only one original source (e.g., at > the moment when an issue is reported there seems to be no way to know whether > the appropriate node has already been processed and its line numbers fixed or > not). > > Is there now with antlr4-based Parrot a decent and reliable solution of this > problem ASTT-level, or should I rather stick with my external solutions with > Groovy 3+? > > Thanks again, > OC >