Right now I am trying to validate, that file doesn't have "violating" imports. As far as i get it preprocessor #include #import macro won't be listed listed in ASTContext and SourceManager (after all they are macro), while you certainly can track ImportDecl during AST traversal.
So the only option left right now to get list of imports is to get files source code and use regular expressions? Maybe there are other "proper" ways?
So basically you can iterate on import declarations using ASTContext - local_imports
Related
I have an Objective-C XCode project open that I originally wrote back in 2018 (about 4 year ago as of the time of this posting).
At that time, the project built with no issues. Now, building the project produces a few errors, including:
Use of undeclared identifier 'kCurrentProcess'
Use of undeclared identifier 'kProcessTransformToForegroundApplication'
Implicit declaration of function 'TransformProcessType' is invalid in C99
A Google search for "kCurrentProcess" turns up little apart from a rather sparse Apple documentation page, whose entire body consists of the following:
Declaration
kCurrentProcess = 2
The hierarchy of that doc page does indicate that kCurrentProcess is a part of something called "ApplicationServices Enumerations", but that's all -- no information on what .h file needs to be imported.
I suppose I could get my program to build by adding my own declaration of kCurrentProcess, like:
#define kCurrentProcess 2
I'd rather import the actual declaration, though.
What do I need to #import in order to pick up the declarations for these "ApplicationServices Enumerations" items?
Through some experimentation, it appears that the requisite import is:
#import <ApplicationServices/ApplicationServices.h>
Adding that to my own .h file corresponding to the .m file where the build errors were occurring resolved the issue for my project.
I'm writing my own compiler and I'm struggling to implement a module system.
Can someone guide me, how should this be done? how other languages tackle this?
Also I'm trying to avoid what c and c++ do (header files).
I do like the module system in Go/Golang though.
I don't know if this is relevant, but I'm using LLVM (maybe there's a magic way to import symbols).
my initial approach:
read and parse the entry point source file ie. main.mylang.
go through the imports of main.mylang
for each import: read, parse and resolve it's imports
...
this leads to a tree structure:
main.mylang: import1.mylang, import2.mylang, import3.mylang
import1.mylang: import4.mylang, import5.mylang
import2.mylang: import6.mylang
... etc.
then I would traverse each node and copy it's symbols (functions, global variables, etc.) to the parent node's symbol table. if a parent node is null, it's an entry point file and the compiler can start output object files.
why do I think that this is bad?
it's very slow, even when compiling 3-5 source files
it's easy to cause name collisions
you have to import the entire symbol table, because the imported file's exported symbols depend on the internal ones.
for example: imagine an exported function that modifies an internal global variable
Thanks in advance
I think your approach is really good. Compile time speed is not that important, usability is. To prevent name collisions you can use some kind of module-namespace (importname.foo() instead of just foo()) and whenever foo does not exist allow both methods. Alternatively you could insert a placeholder in the parents symbol table and whenever the user uses that name you throw a compile time error (something like ambiguous symbol).
that would look like this:
main.mylang
import module1
import module2
int main() {}
module1.mylang
import module2
void foo() {}
void bar() {}
module2.mylang
import module1
void bar() {}
void fun() {}
After finding loops, the tree would look like this:
main
├──module1
│ └──module2
└──module2
└──module1
And a graph like this:
main
├─>main()
├─>foo() (module1)
├─>bar() (defined twice, throw error when used)
├─>fun() (module2)
├─>module1<───────────┐
│ ├─>foo() (module1) │
│ └─>bar() (module1) │
└─>import2<───────────┘
├─>bar() (module2)
└─>fun() (module2)
I don't know much about llvm, but I am pretty sure normal tables are not enough to archive this. You will at least need nested tables if not even a graph like structure like I described. Also this is not possible with classical C/C++ architecture, except if you use unique identifiers as symbols and don't let the user know (like c++ function overloading). For example you could call one function __import1_bar and the other __import2_bar and whenever the user uses bar() you look up in this graph which one he wants to call. In the main function using import1.bar() will lead you to __import1_bar (follow the graph) and import2.bar() or import1.import2.bar() will lead you to __import2_bar.
Good Luck figuring that out. But it is certainly a interesting problem.
In vb.net option statements exist that tell the compiler to ignore or compel to standards set by the user.
In my example:
Option Strict On
Option Explicit Off
Option Infer On
the problem with this is that these statements need to be repeated in every class in order to become active. Is there a way to make these statements active or inactive globally in every class of my project?
Go to: Project Menu->Proj Name Properties->Compile Tab - Compile Options.
Note that any Option __ statements in the code file will override the project wide settings for that file
- TnTinMn
If I have a .less file that imports two other .less files that both use and define the same variable name, the last definition in whichever file was imported last is the value used in all the other files. For example:
#import (less) ex1.less
#import (less) ex2.less
ex1.less:
#var: classname;
.#{var} {/*css*/}
ex2.less:
#var: classname2;
.#{var} {/*css*/}
generates:
.classname2 {/*css*/}
.classname2 {/*css*/}
I am not sure how to use namespaces here, so any help would be very appreciated.
Much like CSS Less cascades it's values, so the last var declaration wins.
You only import one of the files.
Change the second var's name.
Or make one of your less files more concise and use the var where needed.
I would like to use ProGuard to just rename variable and functions. I want the resultant class files to be identical to the source jar in every regard except for the names. Is there an option to do this?
My attempts at using dontoptimize and dontshrink are not working.
Just put the following in your .pro file, and make sure that you don't use the "-keep" option to prevent other things from being obfuscated.
# Don't keep the local variables attributes (LocalVariableTable and LocalVariableTypeTable are dropped).
-keepattributes Exceptions,Signature,Deprecated,SourceFile,SourceDir,LineNumberTable,Synthetic,EnclosingMethod,RuntimeVisibleAnnotations,RuntimeInvisibleAnnotations,RuntimeVisibleParameterAnnotations,RuntimeInvisibleParameterAnnotations,AnnotationDefault,InnerClasses,*Annotation*
In other words, make sure that you don't have the following in your options
-keepattributes LocalVariableTable,LocalVariableTypeTable