1+ package edu .rice .cs .drjava .model .compiler ;
2+
3+ import edu .rice .cs .drjava .model .DJError ;
4+ import edu .rice .cs .drjava .ui .SmartSourceFilter ;
5+ import edu .rice .cs .plt .reflect .JavaVersion ;
6+ import javax .swing .filechooser .FileFilter ;
7+ import java .io .File ;
8+ import java .io .IOException ;
9+ import java .util .*;
10+ import javax .tools .*;
11+
12+ public class JavaxToolsCompiler implements CompilerInterface {
13+
14+ private final JavaCompiler compiler ;
15+
16+ public JavaxToolsCompiler () {
17+ this .compiler = ToolProvider .getSystemJavaCompiler ();
18+ }
19+
20+ public boolean isAvailable () {
21+ return this .compiler != null ;
22+ }
23+
24+ public List <? extends DJError > compile (List <? extends File > files , List <? extends File > classPath ,
25+ List <? extends File > sourcePath , File destination ,
26+ List <? extends File > bootClassPath , String sourceVersion , boolean showWarnings ) {
27+ // Check if compiler is available
28+ if (compiler == null ) {
29+ List <DJError > errors = new ArrayList <>();
30+ errors .add (new DJError ("Compiler is not available" , false ));
31+ return errors ;
32+ }
33+
34+ // Set up the file manager
35+ StandardJavaFileManager fileManager = compiler .getStandardFileManager (null , null , null );
36+
37+ // Set the classpath, source path, and bootclasspath
38+ try {
39+ if (classPath != null ) {
40+ fileManager .setLocation (StandardLocation .CLASS_PATH , classPath );
41+ }
42+ if (sourcePath != null ) {
43+ fileManager .setLocation (StandardLocation .SOURCE_PATH , sourcePath );
44+ }
45+ if (bootClassPath != null ) {
46+ fileManager .setLocation (StandardLocation .PLATFORM_CLASS_PATH , bootClassPath );
47+ }
48+ } catch (IOException e ) {
49+ List <DJError > errors = new ArrayList <>();
50+ errors .add (new DJError ("Error setting paths: " + e .getMessage (), false ));
51+ return errors ;
52+ }
53+
54+ // Convert files to a format the compiler understands
55+ Iterable <? extends JavaFileObject > compilationUnits = fileManager .getJavaFileObjectsFromFiles (files );
56+
57+ // Prepare the compilation options
58+ List <String > optionList = new ArrayList <>();
59+ if (sourceVersion != null ) {
60+ optionList .add ("-source" );
61+ optionList .add (sourceVersion );
62+ }
63+ if (destination != null ) {
64+ optionList .add ("-d" );
65+ optionList .add (destination .getAbsolutePath ());
66+ }
67+ if (showWarnings ) {
68+ optionList .add ("-Xlint" );
69+ } else {
70+ optionList .add ("-Xlint:none" );
71+ }
72+
73+ // Prepare a diagnostic collector to collect compile errors
74+ DiagnosticCollector <JavaFileObject > diagnostics = new DiagnosticCollector <>();
75+
76+ // Create a compilation task
77+ JavaCompiler .CompilationTask task = compiler .getTask (null , fileManager , diagnostics , optionList , null , compilationUnits );
78+
79+ // Perform the compile task
80+ boolean success = task .call ();
81+
82+ // Process diagnostics to create DJError list
83+ List <DJError > errors = new ArrayList <>();
84+ for (Diagnostic <? extends JavaFileObject > diagnostic : diagnostics .getDiagnostics ()) {
85+ DJError error = new DJError (new File (diagnostic .getSource ().toUri ()),
86+ (int ) diagnostic .getLineNumber (),
87+ (int ) diagnostic .getColumnNumber (),
88+ diagnostic .getMessage (null ),
89+ diagnostic .getKind () == Diagnostic .Kind .ERROR );
90+ errors .add (error );
91+ }
92+
93+ // If compilation failed and no errors were reported, add a generic error message
94+ if (!success && errors .isEmpty ()) {
95+ errors .add (new DJError ("Compilation failed with unknown error" , true ));
96+ }
97+
98+ return errors ;
99+ }
100+
101+ public JavaVersion version () {
102+ return JavaVersion .JAVA_8 ;
103+ }
104+
105+ public String getName () {
106+ return "javax.tools" ;
107+ }
108+
109+ public String getDescription () {
110+ return "Custom compiler implementation using javax.tools" ;
111+ }
112+
113+ public String toString () {
114+ return getName ();
115+ }
116+
117+ public List <File > additionalBootClassPathForInteractions () {
118+ // TODO: figure out what this looks like for javax.tools compiler
119+ return new ArrayList <File >();
120+ }
121+
122+ public String transformCommands (String interactionsString ) {
123+ // TODO: Implement command transformation logic (this is for interpreter)
124+ return interactionsString ;
125+ }
126+
127+ public boolean isSourceFileForThisCompiler (File f ) {
128+ if (f == null ) return false ;
129+ String fileName = f .getName ();
130+ return fileName .endsWith (".java" );
131+ }
132+
133+ public Set <String > getSourceFileExtensions () {
134+ HashSet <String > extensions = new HashSet <String >();
135+ extensions .add ("java" );
136+ return extensions ;
137+ }
138+
139+ public String getSuggestedFileExtension () {
140+ return ".java" ;
141+ }
142+
143+ public FileFilter getFileFilter () {
144+ // TODO: this might need to be different... (I think smartsourcefilter includes .dj files which idk ab)
145+ return new SmartSourceFilter ();
146+ }
147+
148+ public String getOpenAllFilesInFolderExtension () {
149+ // Should we use OptionConstants for this?
150+ return ".java" ;
151+ }
152+
153+ /** Return the set of keywords that should be highlighted in the specified file.
154+ * @param f file for which to return the keywords
155+ * @return the set of keywords that should be highlighted in the specified file. */
156+ public Set <String > getKeywordsForFile (File f ) { return new HashSet <>(JAVA_KEYWORDS ); }
157+
158+ /** Set of Java/GJ keywords for special coloring. */
159+ public static final HashSet <String > JAVA_KEYWORDS = new HashSet <>();
160+ static {
161+ final String [] words = {
162+ "import" , "native" , "package" , "goto" , "const" , "if" , "else" , "switch" , "while" , "for" , "do" , "true" , "false" ,
163+ "null" , "this" , "super" , "new" , "instanceof" , "return" , "static" , "synchronized" , "transient" , "volatile" ,
164+ "final" , "strictfp" , "throw" , "try" , "catch" , "finally" , "throws" , "extends" , "implements" , "interface" , "class" ,
165+ "break" , "continue" , "public" , "protected" , "private" , "abstract" , "case" , "default" , "assert" , "enum"
166+ };
167+ Collections .addAll (JAVA_KEYWORDS , words );
168+ }
169+
170+ public boolean supportsLanguageLevels () {
171+ // TODO: should we support LanguageLevels?
172+ return false ;
173+ }
174+ }
0 commit comments