I want to extract the line number with the comment line from the source code with the codes below
foreach (Match match in re.Matches(FileText))
{
StackFrame CallStack = new StackFrame(0, true);
sb.Append(match.ToString() + CallStack.GetFileLineNumber() + System.Environment.NewLine);
}
return sb.ToString();
How do I capture each comment with line number e.g. /* Test Comment */ Line: 50
There is no "docs" in the assembly. The docs are generated in form of an XML file and should be distributed along with the assembly. From the call stack, you can get the names of the classes and methods. If you know where the XML files are sitting, then you can for example refer to http://jimblackler.net/blog/?p=49 they have the reading of docs per a method mostly done.
However, this is NOT the way the .Net does such things. For having extra compile-time annotations that will survive the compilation and that will be present during the runtime, the .Net allows you to introduce CustomAttributes that can be applied over methods, classes, fields, properties, enums, (....). See that link, look at the example of "Author" attribute and consider changing the magic comment into an attribute. This is the normal way of doing it in whole .Net, not only C#.
Once you read the MethodInfo from the callstack, you can invoke GetCustomAttributes on it, and read the data that you have written in them, see http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.aspx
Related
I've written a number of Java annotation processors that write some arbitrary data to text files that will be included in my class directory / jar file. I typically use code that looks like this:
final OutputStream out = processingEnv
.getFiler()
.createResource(StandardLocation.CLASS_OUTPUT, "", "myFile")
.openOutputStream();
I'm trying to do something similar in a groovy ASTTransformation. I've tried adding a new source file but that (expectedly) must be valid groovy. How do I write arbitrary resources from an ASTTransformation? Is it even possible?
As part of implementing your ASTTransformation, you need to implement the void visit(ASTNode[] nodes, SourceUnit source) method. In it you can call source.getConfiguration().getTargetDirectory() and it will return your build output directory, e.g. /Users/skissane/my-groovy-project/build/classes/groovy/main). You can then write your resources into there, and whatever is packaging them into the JAR (such as Gradle) should pull them from that.
In my case, I wanted to delay writing the resources until OUTPUT phase – since I was creating META-INF/services files, and I wanted to wait until I'd seen all the annotated classes before writing them, or else I'd be repeatedly adding to them for each annotated class – so I also implemented CompilationUnitAware, and then in my setCompilationUnit method I call unit.addPhaseOperation() and pass it a method reference to run during OUTPUT. Note, if you are using a local ASTTransformation, setCompilationUnit will be called multiple times (each time on a new instance of your transformation class); to avoid adding the phase operation repeatedly, I used a map in a static field to track if I'd seen this CompilationUnit before or not. My addPhaseOperation method is called once per an output class, so I used a boolean field to make sure I only wrote the resource files out once.
Doing this caused a warning to be printed:
> Task :compileGroovy
warning: Implicitly compiled files were not subject to annotation processing.
Use -implicit to specify a policy for implicit compilation.
1 warning
Adding this to build.gradle made the warning go away:
compileGroovy {
options.compilerArgs += ['-implicit:none']
}
Hopefully this is what my problem is(having problem reading the error log that erlang prints). I'm trying to search through a list to find a matching string(PID from a client converted to a string) but it just results in a crash.
...
#7 ClientPID = pid_to_list(From),
#8 list:member(ClientPID, #server.users), % 'users' being a list in the record 'server'
...
The 'users' list in the 'server' record is just defined to users = [], if it helps.
Crash report:
** Reason for termination ==
** "{undef,[{list,member,[\"<0.568.0>\",2],[]}, {server,loop,2,[{file,\"server.erl\"},{line,8}]},
{genserver,loop,2,[{file,\"c:/Erlang/ServCli/genserver.erl\"}{line,13}]}]}"
Module is called lists not list. It's common mistake :)
And your argument are little off. You are using record, and proper usage look like this: VariableThatStoresRecord#record_name.filed_name. In your case it could be something like State#state.users (or just shorten State parameter in loop function to S if you don't like this double state).
What you are doing is actually a semantic suger, which returns on which element in record/tuple given field is stored (since all records are in fact tuples). In you case #state.users returns 2 (first element is record name, and I guess that users is first defined field in your record).
Regarding the error message. First thing is thing you get undef error. So it means that you are meking call to undefined function (which is quite common, since Erlang is dynamic language). Than you get list of tuples, which represents call-trace, from newest to oldest like this
[ { function call definition }
{ function call definition }
{ function call definition } ]
The first one is most interesting, since it is the call to undefined function. You can see that it is call to module list and function member. Other than that you can expect either actual arguments, or just arrity (those variables could be garbage collected already in erlang), and some information about function definition (like file and line number).
And from {list,member,[\"<0.568.0>\",2],[]} you can see that you are trying to call list:member function, with arguments "<0.568.0>" and 2. If you change your call to lists:member(ClientPID, Server#server.users) it should work.
Since most of the error messages are usually nested tuples/lists, which are hard to read if they are presented in one line. So what I do is copy them to my editor, split the one-liner into multiple lines, and than auto indent (emacs does this really great, and some editor can follow this lisp-like indention for Erlang).
I was wondering whether one can influence the "style" of the code that JAXB generates from XML schema (.xsd) fles. E.g. I would like to:
emit a comment inside newly generated classes, specifically if the class is empty, since that triggers warnings in my environment.
change all setter-methods to return the object instead of "void", so one can do call-chaining like:
X someMethod() {
return new X().setFoo(5).setBar("something");
}
instead of the tedious:
X someMethod() {
X x = new (X);
x.setFoo(5);
x.setBar("something");
return x;
}
Is there some "template" anywhere that JAXB uses and that one could tweak, to achieve such things? Or is that all hard-coded?
M.
There is no template for modifying the generated code easily.
There is, however, a number of plugins. For instance: https://java.net/projects/jaxb2-commons/pages/Fluent-api which is just what you want according to your 2nd bullet.
There are other plugins, e.g. for annotations suppressing warnings - that may help against the 1st bullet.
As an extra, I'd like to mention that not generating Java classes from an XML schema but writing them by hand (plus annotations, of course) is a plausible alternative, provided the XML schema isn't too complex. It may have other advantages besides solving #1 and #2.
This question is with reference to the Cymbol code from the book (~ page 143) :
int t = ctx.type().start.getType(); // in DefPhase.enterFunctionDecl()
Symbol.Type type = CheckSymbols.getType(t);
What does each component return: "ctx.type()", "start", "getType()" ? The book does not contain any explanation about these names.
I can "kind of" understand that "ctx.type()" refers to the "type" rule, and "getType()" returns the number associated with it. But what exactly does the "start" do?
Also, to generalize this question: what is the mechanism to get the value/structure returned by a rule - especially in the context of usage in a listener?
I can see that for an ID, it is:
String name = ctx.ID().getText();
And as in above, for an enumeration of keywords it is via "start.getType()". Any other special kinds of access that I should be aware of?
Lets disassemble problem step by step. Obviously, ctx is instance of CymbolParser.FunctionDeclContext. On page 98-99 you can see how grammar and ParseTree are implemented (at least the feeling - for real implementation please see th .g4 file).
Take a look at the figure of AST on page 99 - you can see that node FunctionDeclContext has a several children, one labeled type. Intuitively you see that it somehow correspond with function return-type. This is the node you retrieve when calling CymbolParser.FunctionDeclContext::type. The return type is probably sth like TypeContext.
Note that methods without 'get' at the beginning are usually children-getters - e.g. you can access the block by calling CymbolParser.FunctionDeclContext::block.
So you got the type context of the method you got passed. You can call either begin or end on any context to get first of last Token defining the context. Simply start gets you "the first word". In this case, the first Token is of course the function return-type itsef, e.g. int.
And the last call - Token::getType returns integral representation of Token.
You can find more information at API reference webpages - Context, Token. But the best way of understanding the behavior is reading through the generated ANTLR classes such as <GrammarName>Parser etc. And to be complete, I attach a link to the book.
Using the MFCApplication wizard in Visual C++ 2012, if "Generate attributed database class" is checked, a header with some special syntax (attributed C++ classes) are generated, which look like this:
// MFCApplication2Set.h: interface of the CMFCApplication2Set class
//
#pragma once
// code generated on March-05-13, 9:26 AM
[
db_source(L"Provider=SQLNCLI11.1;..."),
db_table(L"dbo.tblEmployee")
]
class CMFCApplication2Set
{
public:
... big list of stuff that corresponds to the fields in your db table omitted ...
}
The above header corresponds to a mostly empty implementation file:
// MFCApplication2Set.cpp : implementation of the CMFCApplication2Set class
//
#include "stdafx.h"
#include "MFCApplication2.h"
#include "MFCApplication2Set.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMFCApplication2Set implementation
That was the WHOLE implementation class. Notice that:
A. No parent class name is specified anywhere.
B. There's some "Visual C++ magic" going on here, that is, as a novice to modern C++, I'm lost.
db_source is documented here but the documentation is pretty thin or at least opaque to me.
Questions:
I was mystified by this syntax when I first saw it, but I figured out it's probably a variant of this Attributes feature in Visual C++. It is that, right?
How am I meant to I use these generated "attributed database class" objects? I found this documentation but if you look carefully at that documentation, that code sample is showing people the Old Way and the New Way, and is not telling me what I want to know which is how to use this new object that the IDE can not give me any documentation or code completion features for. Also since the generated code for the CMFCApplication2Set class generated by the wizard does not reference any types or class names, I'm lost. If I could even use some IDE feature to know what methods and stuff have been Magically Injected into this Magical mystery Object, I'd be better off. The only think I can think to do is to learn the old way and learn all the things you can call from the old two-separate-ATL-types world, and then somehow learn to combine them.
In a nutshell, I'm looking for the minimum syntax I need to know to actually use one of these Attributed Database Class instances, variables, as they are generated in a new MFC app by the wizard. The instance shown below is a member of an MFC document class and CMFCApplication2Set m_MFCApplication2Set is declared as a field inside the MFC document class.
What I have tried is to use this "untyped object". This object appears to have lots of data fields (m_X) and has only one method that shows up in IDE code completion, called GetRowSetProperties. Thanks to whatever magic or injection is going on, this generated Attributed Database Class (which does not visibly inherit anything) is a complete mystery to me at edit time and compile time.
Here's me just trying to inspect this thing to see if it even initialized itself when its constructor ran:
BOOL CMFCApplication2Doc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE;
TRACE( m_MFCApplication2Set.m_AStringFieldName); // outputs NOISE.
return TRUE; }
At compile time and edit time, the IDE gives me NO help about the types involved in this "anonymous" class that inherits from nothing, but which gets lots of secret powers due to some kind of Injection via those attributes I'm guessing. At debug time, I can see that there is more than just a bunch of data fields in this C++ class, but this still doesn't help me know how to use it. A minimal code sample of using one of these to go get a recordset from the database, would be great.
Update: Calling OpenDataSource is fun, because it compiles but the IDE doesn't think it should be valid. Nevertheless, it runs, and returns 0 as the result, but that doesn't actually initialize this CThingyThatVisualStudioGaveYouThatYouDontKnowWhatItIs:
This is a deprecated feature of attributed C++ code. Pre-processor expands code and replaces attributes with actual base classes. If you enable generation of these intermediate files, things are going to be more clear to you:
You will have XXX.mrg.cpp and XXX.mrg.h files generated, which you can review and see the real C++ code forwarded to compiler.
The attributes will be replaced with substituted bases classes, maps like BEGIN_COLUMN_MAP etc. The attributed source code is compact, but the feature is deprecated and looking into expanded code it should be easy (if necessary) to strip the attributes and copy expanded code right into source. It's easy with DB attributes, and more difficult with COM attributes since the internal dependencies are most sophisticated.