Java tutorial
/** * <small> * <p><i>Copyright (C) 2005 Torsten Juergeleit, * All rights reserved. </i></p> * * <p>USE OF THIS CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS * AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES * INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE * OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS * OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED * BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND * THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES * INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p> * * <p>This Content is Copyright (C) 2005 Torsten Juergeleit, * and is provided to you under the terms and conditions of the Common Public * License Version 1.0 ("CPL"). A copy of the CPL is provided with this Content * and is also available at * <a href="http://www.eclipse.org/legal/cpl-v10.html"> * http://www.eclipse.org/legal/cpl-v10.html </a>. * * For purposes of the CPL, "Program" will mean the Content.</p> * * <p>Content includes, but is not limited to, source code, object code, * documentation and any other files in this distribution.</p> * * </small> */ package org.antlr.eclipse.core.builder; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import org.antlr.eclipse.core.AntlrCorePlugin; import org.antlr.eclipse.core.AntlrNature; import org.antlr.eclipse.core.properties.SettingsPersister; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import antlr.AntlrTool; /** * An eclipse builder to compile ANTLR grammars */ public class AntlrBuilder extends IncrementalProjectBuilder implements IStreamListener { /** the builder id */ public static final String BUILDER_ID = AntlrCorePlugin.PLUGIN_ID + ".antlrbuilder"; /** the builder debug id */ public static final String DEBUG_OPTION = AntlrCorePlugin.PLUGIN_ID + "/builder/debug"; /** are we debugging the builder? */ public static boolean DEBUG = false; private IFile fFile; private String fOutput; private PrintStream fOriginalOut; private PrintStream fOriginalErr; /** the persistent option that indicates that a generated file should have warnings cleared */ public static final QualifiedName CLEAN_WARNINGS = new QualifiedName(AntlrCorePlugin.PLUGIN_ID, SettingsPersister.CLEAN_WARNINGS); /** the persistent option that indicates that a generated file should have warnings cleared */ public static final QualifiedName INSTALL_SMAP = new QualifiedName(AntlrCorePlugin.PLUGIN_ID, SettingsPersister.SMAP_PROPERTY); /** the persistent option that attaches a grammar name to a file it generated */ public static final QualifiedName GRAMMAR_ECLIPSE_PROPERTY = new QualifiedName(AntlrCorePlugin.PLUGIN_ID, SettingsPersister.GRAMMAR_PROPERTY); /** the persistent option that attaches command line options to generated file */ public static final QualifiedName COMMAND_LINE_OPTIONS_PROPERTY = new QualifiedName(AntlrCorePlugin.PLUGIN_ID, "commandLineOptions"); /** * Create a builder */ public AntlrBuilder() { DEBUG = AntlrCorePlugin.isDebug(DEBUG_OPTION); } /** {@inheritDoc} */ @Override protected void clean(IProgressMonitor monitor) throws CoreException { // delete all derived resources that have a GRAMMAR option on them getProject().accept(new CleaningVisitor(monitor, null)); } /** Simple visitor collecting files with .g extension */ private class GrammarCollectorVisitor implements IResourceVisitor { private ArrayList<IFile> files = new ArrayList<IFile>(); public ArrayList<IFile> getFiles() { return files; } @Override public boolean visit(IResource resource) throws CoreException { if (resource instanceof IFile) { IFile file = (IFile) resource; if (file.getName().endsWith(".g")) { files.add(file); } } return true; } } /** * Walks the super grammars and imported vocabularies of the provided file. * And returns the topological ordering of the grammars. * * @param file the file to process * @param result the topologically ordered list of grammars. * */ private void depthWalk(final IFile file, LinkedList<IFile> result) { HashMap<String, HashMap<String, String>> map = SettingsPersister.readSettings(file.getProject()); // Get super grammars from grammar properties String superGrammars = SettingsPersister.get(map, file, SettingsPersister.SUPER_GRAMMARS_PROPERTY); String importVocabularies = SettingsPersister.get(map, file, SettingsPersister.IMPORT_VOCABULARIES_PROPERTY); if (superGrammars == null || superGrammars.trim().isEmpty()) { // Try to get // -glib parameter from comment in .g file. This // enables sharing in a team project without local reconfiguration String localSuperGrammar = extractGlibComment(file); if (localSuperGrammar != null) { superGrammars = convertFolderRelatedPath(localSuperGrammar); } } if (superGrammars == null && importVocabularies == null) { return; } //tokenize && walk IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); if (superGrammars != null) { StringTokenizer tokenizer = new StringTokenizer(superGrammars, ";"); while (tokenizer.hasMoreTokens()) { String grammar = tokenizer.nextToken(); IResource resource = root.findMember(grammar); if (resource != null && resource instanceof IFile) { IFile superFile = (IFile) resource; if (!result.contains(superFile)) { depthWalk(superFile, result); result.add(superFile); } } } } if (importVocabularies != null) { StringTokenizer tokenizer = new StringTokenizer(importVocabularies, ";"); while (tokenizer.hasMoreTokens()) { String grammar = tokenizer.nextToken(); IResource resource = root.findMember(grammar); if (resource != null && resource instanceof IFile) { IFile superFile = (IFile) resource; if (!result.contains(superFile)) { depthWalk(superFile, result); result.add(superFile); } } } } } /** * Calculate the topological ordering of grammars. * * @param files the list of grammar file to process * * @return the topologically ordered list of grammars. * */ private LinkedList<IFile> topologicalOrdering(ArrayList<IFile> files) { LinkedList<IFile> result = new LinkedList<IFile>(); for (IFile file : files) { depthWalk(file, result); if (!result.contains(file)) { result.add(file); } } return result; } /** {@inheritDoc} */ @Override protected IProject[] build(int aKind, Map<String, String> anArgs, IProgressMonitor aMonitor) throws CoreException { IProject project = getProject(); if (!AntlrNature.hasNature(project)) { return null; } if (aKind == FULL_BUILD) { GrammarCollectorVisitor visitor = new GrammarCollectorVisitor(); project.accept(visitor); ArrayList<IFile> files = visitor.getFiles(); LinkedList<IFile> orderedFiles = topologicalOrdering(files); for (int i = 0; i < orderedFiles.size(); i++) { IFile file = orderedFiles.get(i); compileFile(file, aMonitor); } } else { IResourceDelta delta = getDelta(project); delta.accept(new DeltaVisitor(aMonitor)); } return null; } /** {@inheritDoc} */ @Override public void streamAppended(String aText, Object aStream) { if (DEBUG) { fOriginalOut.println("ANTLR output: " + aText); } int line = 0; String message = null; int severity = 0; // First check for messages with header "<file>|<line>|<column>" StringTokenizer st = new StringTokenizer(aText, "|"); if (st.countTokens() > 3) { st.nextToken(); // file line = Integer.parseInt(st.nextToken()); Integer.parseInt(st.nextToken()); // column message = st.nextToken(); while (st.hasMoreTokens()) { message += st.nextToken(); } if (message.startsWith("warning:")) { severity = IMarker.SEVERITY_WARNING; message = message.substring(8); } else { severity = IMarker.SEVERITY_ERROR; } message = message.replace('\t', ' ').trim(); // Then check for messages without header } else if (aText.startsWith("panic: ")) { message = aText.substring(7); severity = IMarker.SEVERITY_ERROR; } else if (aText.startsWith("error: ")) { message = aText.substring(7); severity = IMarker.SEVERITY_ERROR; } else if (aText.startsWith("warning: ")) { severity = IMarker.SEVERITY_WARNING; message = aText.substring(9); } else { if (DEBUG) { fOriginalOut.println("Unhandled ANTLR output: " + aText); } } // If valid error/warning message found then create problem marker if (message != null) { createProblemMarker(line, message, severity); } } private void createProblemMarker(int aLine, String aMessage, int aSeverity) { try { IMarker marker = fFile.createMarker(IMarker.PROBLEM); marker.setAttribute(IMarker.MESSAGE, aMessage); marker.setAttribute(IMarker.SEVERITY, aSeverity); if (aLine > 0) { marker.setAttribute(IMarker.LINE_NUMBER, aLine); } } catch (CoreException e) { AntlrCorePlugin.log(e); } } private class DeltaVisitor implements IResourceDeltaVisitor { private IProgressMonitor fMonitor; /** * Create a delta visitor * @param aMonitor A progress monitor */ public DeltaVisitor(IProgressMonitor aMonitor) { fMonitor = aMonitor; } /** {@inheritDoc} */ @Override public boolean visit(IResourceDelta aDelta) { boolean visitChildren = false; IResource resource = aDelta.getResource(); if (resource instanceof IProject) { // Only check projects with ANTLR nature IProject project = (IProject) resource; visitChildren = AntlrNature.hasNature(project); } else if (resource instanceof IFolder) { visitChildren = true; } else if (resource instanceof IFile) { // Only check ANTLR grammar files IFile file = (IFile) resource; String ext = file.getFileExtension(); if (file.exists() && ext != null && ext.equals("g")) { switch (aDelta.getKind()) { case IResourceDelta.ADDED: case IResourceDelta.CHANGED: compileFile(file, fMonitor); visitChildren = true; break; case IResourceDelta.REMOVED: // delete the old generated files for this grammar try { String grammarFileName = file.getProjectRelativePath().toString(); file.getProject().accept(new CleaningVisitor(fMonitor, grammarFileName)); } catch (CoreException e) { AntlrCorePlugin.log(e); } visitChildren = true; break; } } } return visitChildren; } } /** * Compile a grammar * @param aFile The grammar file to compile * @param aMonitor A progress monitor */ public void compileFile(IFile aFile, IProgressMonitor aMonitor) { String grammarFileName = aFile.getProjectRelativePath().toString(); try { // delete the old generated files for this grammar aFile.getProject().accept(new CleaningVisitor(aMonitor, grammarFileName)); // if it's in a java project, only build it if it's in a source dir if (aFile.getProject().hasNature(JavaCore.NATURE_ID)) { IProject project = aFile.getProject(); IJavaProject javaProject = JavaCore.create(project); IPath path = aFile.getFullPath(); boolean ok = false; IClasspathEntry[] resolvedClasspath = javaProject.getResolvedClasspath(true); for (int i = 0; i < resolvedClasspath.length; i++) { IClasspathEntry entry = resolvedClasspath[i]; if (entry.getEntryKind() != IClasspathEntry.CPE_SOURCE) continue; IPath entryPath = entry.getPath(); if (entryPath.isPrefixOf(path)) { ok = true; break; } } if (!ok) { return; } } } catch (CoreException e1) { e1.printStackTrace(); } fFile = aFile; aMonitor.beginTask( AntlrCorePlugin.getFormattedMessage("AntlrBuilder.compiling", aFile.getFullPath().toString()), 4); // Remove all markers from this file try { aFile.deleteMarkers(null, true, IResource.DEPTH_INFINITE); } catch (CoreException e) { AntlrCorePlugin.log(e); } // Prepare arguments for ANTLR compiler // read the settings for this grammar HashMap<String, HashMap<String, String>> map = SettingsPersister.readSettings(aFile.getProject()); ArrayList<String> args = createArguments(map, aFile); if (DEBUG) { System.out.println("Compiling ANTLR grammar '" + aFile.getName() + "': arguments=" + args); } // Monitor system out and err fOriginalOut = System.out; fOriginalErr = System.err; System.setOut(new PrintStream(new MonitoredOutputStream(this))); System.setErr(new PrintStream(new MonitoredOutputStream(this))); try { // Compile ANTLR grammar file AntlrTool tool = new AntlrTool(); if (!tool.preprocess(args.toArray(new String[args.size()]))) { try { aMonitor.worked(1); if (!tool.parse()) { aMonitor.worked(1); if (!tool.generate()) { aMonitor.worked(1); refreshFolder(map, tool, args, aFile, grammarFileName, ResourcesPlugin.getWorkspace().getRoot().findMember(fOutput), aMonitor, tool.getSourceMaps()); } else { // If errors during generate then delete all // generated files deleteFiles(tool, aFile.getParent(), aMonitor); } aMonitor.worked(1); } } catch (CoreException e) { AntlrCorePlugin.log(e); } } } catch (Throwable e) { if (!(e instanceof SecurityException)) { AntlrCorePlugin.log(e); } } finally { System.setOut(fOriginalOut); System.setErr(fOriginalErr); aMonitor.done(); } } /** * Returns list of commandline arguments for ANTLR compiler. * @param map the saved antlr-eclipse settings for this project * @param file The grammar file to parse * @return a list of command-line arguments */ private ArrayList<String> createArguments(HashMap<String, HashMap<String, String>> map, IFile file) { ArrayList<String> args = new ArrayList<String>(); AntlrCorePlugin.getDefault().upgradeOldSettings(file, map); fOutput = SettingsPersister.get(map, file, SettingsPersister.OUTPUT_PROPERTY); // Prepare absolute output path (-o) String outputPath = null; if (fOutput != null && fOutput.trim().length() > 0) { outputPath = convertRootRelatedPath(fOutput); } if (outputPath == null) { fOutput = fFile.getParent().getFullPath().toOSString(); outputPath = fFile.getParent().getLocation().toOSString(); } args.add("-o"); args.add(outputPath); // Get boolean options from grammar properties addBooleanGrammarProperty(map, file, SettingsPersister.DEBUG_PROPERTY, "-debug", null, args, false); addBooleanGrammarProperty(map, file, SettingsPersister.HTML_PROPERTY, "-html", null, args, false); addBooleanGrammarProperty(map, file, SettingsPersister.DOCBOOK_PROPERTY, "-docbook", null, args, false); addBooleanGrammarProperty(map, file, SettingsPersister.DIAGNOSTIC_PROPERTY, "-diagnostic", null, args, false); addBooleanGrammarProperty(map, file, SettingsPersister.TRACE_PROPERTY, "-trace", null, args, false); addBooleanGrammarProperty(map, file, SettingsPersister.TRACE_PARSER_PROPERTY, "-traceParser", null, args, false); addBooleanGrammarProperty(map, file, SettingsPersister.TRACE_LEXER_PROPERTY, "-traceLexer", null, args, false); addBooleanGrammarProperty(map, file, SettingsPersister.TRACE_TREE_PARSER_PROPERTY, "-traceTreeParser", null, args, false); addBooleanGrammarProperty(map, file, SettingsPersister.SMAP_PROPERTY, "-smap", null, args, true); // Get super grammars from grammar properties String superGrammars = SettingsPersister.get(map, file, SettingsPersister.SUPER_GRAMMARS_PROPERTY); // Prepare optional super grammar(s) (-glib) // Can be defined in two ways : in a property dialog OR // inside the grammar using a comment "// -glib <file in same folder>" if (superGrammars != null && superGrammars.trim().length() > 0) { superGrammars = convertRootRelatedPathList(superGrammars); if (superGrammars != null) { args.add("-glib"); args.add(superGrammars); } } else { // Try to get // -glib parameter from comment in .g file. This // enables sharing in a team project without local reconfiguration String localSuperGrammar = extractGlibComment(fFile); if (localSuperGrammar != null) { localSuperGrammar = convertFolderRelatedPath(localSuperGrammar); if (localSuperGrammar != null) { args.add("-glib"); args.add(localSuperGrammar); } } } // Prepare ANTLR grammar file which needs to be compiled args.add(fFile.getLocation().toOSString()); return args; } private void addBooleanGrammarProperty(HashMap<String, HashMap<String, String>> map, IResource grammar, String propertyName, String option, String option2, ArrayList<String> args, boolean defaultValue) { boolean value; String stringValue = SettingsPersister.get(map, grammar, propertyName); if (stringValue == null) value = defaultValue; else value = "true".equalsIgnoreCase(stringValue); if (value) { args.add(option); if (option2 != null) args.add(option2); } } /** * Converts given path (related to workspace root) to an absolute path. * @param aPath The path to convert * @return The converted path */ private String convertRootRelatedPath(String aPath) { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IResource resource = root.findMember(aPath); if (resource == null) { createProblemMarker(0, AntlrCorePlugin.getFormattedMessage("AntlrTool.error.noGrammarFile", aPath), IMarker.SEVERITY_ERROR); } return (resource != null ? resource.getLocation().toOSString() : null); } /** * Converts given list of paths (related to workspace root) to a new list * with absolute paths (delimited by ';'). * @param aPathList The paths to convert * @return The converted paths */ private String convertRootRelatedPathList(String aPathList) { StringBuffer list = new StringBuffer(); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); StringTokenizer tokenizer = new StringTokenizer(aPathList, ";"); while (tokenizer.hasMoreTokens()) { String grammar = tokenizer.nextToken(); IResource resource = root.findMember(grammar); if (resource != null) { list.append(resource.getLocation().toOSString()); if (tokenizer.hasMoreTokens()) { list.append(';'); } } else { createProblemMarker(0, AntlrCorePlugin.getFormattedMessage("AntlrTool.error.noGrammarFile", grammar), IMarker.SEVERITY_ERROR); } } return list.toString(); } /** * Converts given path (related to folder of grammar file) to an absolute * path. * @param aPath The path to convert * @return The converted paths */ private String convertFolderRelatedPath(String aPath) { IResource resource = fFile.getParent().findMember(aPath.toString()); if (resource == null) { createProblemMarker(0, AntlrCorePlugin.getFormattedMessage("AntlrTool.error.noGrammarFile", aPath), IMarker.SEVERITY_ERROR); } return (resource != null ? resource.getLocation().toOSString() : null); } private void deleteFiles(AntlrTool aTool, IContainer aFolder, IProgressMonitor aMonitor) { Iterator<String> files = aTool.files(); while (files.hasNext()) { String fileName = files.next(); if (DEBUG) { fOriginalOut.println("Deleting ANTLR generated file '" + fileName + "'"); } IResource file = aFolder.findMember(fileName); if (file != null) { aMonitor.subTask(AntlrCorePlugin.getFormattedMessage("AntlrBuilder.deleting", fileName)); try { file.delete(true, aMonitor); } catch (CoreException e) { AntlrCorePlugin.log(e); } } } } private void refreshFolder(HashMap<String, HashMap<String, String>> map, AntlrTool aTool, ArrayList<String> args, IFile grammarFile, String grammarFileName, IResource aFolder, IProgressMonitor aMonitor, Map<String, Map<Integer, List<Integer>>> sourceMaps) { aMonitor.subTask( AntlrCorePlugin.getFormattedMessage("AntlrBuilder.refreshing", aFolder.getFullPath().toString())); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IContainer folder = root.getContainerForLocation(aFolder.getLocation()); if (DEBUG) { fOriginalOut.println("Refreshing output folder '" + folder.getFullPath() + "'"); } try { StringBuffer argString = new StringBuffer(); for (Iterator<String> i = args.iterator(); i.hasNext();) { String arg = i.next(); argString.append(arg); argString.append("|"); } ArrayList<IFile> compilationUnitFiles = new ArrayList<IFile>(); Iterator<String> files = aTool.files(); while (files.hasNext()) { String fileName = files.next(); if (DEBUG) { fOriginalOut.println("ANTLR generated file '" + fileName + "'"); } IFile file = folder.getFile(new Path(fileName)); file.refreshLocal(IResource.DEPTH_ZERO, aMonitor); // SASSAS check if file is being edited - if so, refresh file.setDerived(true); String cleanWarnings = SettingsPersister.get(map, grammarFile, SettingsPersister.CLEAN_WARNINGS); String installSmap = SettingsPersister.get(map, grammarFile, SettingsPersister.SMAP_PROPERTY); file.setPersistentProperty(CLEAN_WARNINGS, cleanWarnings); file.setPersistentProperty(INSTALL_SMAP, installSmap); file.setPersistentProperty(GRAMMAR_ECLIPSE_PROPERTY, grammarFileName); file.setPersistentProperty(COMMAND_LINE_OPTIONS_PROPERTY, argString.toString()); if (fileName.endsWith(".java")) { compilationUnitFiles.add(file); Map<Integer, List<Integer>> sourceMap = sourceMaps.get(file.getName()); // add source mappings to the generated file if (sourceMap != null) for (Iterator<Integer> i = sourceMap.keySet().iterator(); i.hasNext();) { Integer sourceLine = i.next(); List<Integer> targetLines = sourceMap.get(sourceLine); for (Iterator<Integer> j = targetLines.iterator(); j.hasNext();) { Integer targetLine = j.next(); IMarker marker = file.createMarker(AntlrCorePlugin.SOURCE_MAPPING_MARKER); marker.setAttribute(AntlrCorePlugin.GRAMMAR_LINE_ATTRIBUTE, sourceLine); marker.setAttribute(AntlrCorePlugin.GENERATED_LINE_ATTRIBUTE, targetLine); } } } } // WORK-IN-PROGRESS -- NON FUNCTIONAL // if (!compilationUnitFiles.isEmpty()) { // // find "end of imports" marker in generated code: // // $$END-OF-ANTLR-GENERATED-IMPORTS$$ // int[] oldImportEnds = findEndOfImports(compilationUnitFiles); // // MultiStatus status = new MultiStatus(AntlrCorePlugin.PLUGIN_ID, 0, "", null); // new ImportOrganizer().organizeImports(compilationUnitFiles, status, aMonitor); // if (status.getSeverity() != IStatus.OK) // AntlrCorePlugin.log(status); // for (Iterator i = compilationUnitFiles.iterator(); i.hasNext();) { // IFile file = (IFile)i.next(); // file.setDerived(true); // } // // // find "end of imports" markers after the organize imports // int[] newImportEnds = findEndOfImports(compilationUnitFiles); // // // adjust the smap files based on the offsets // adjustSmapFiles(compilationUnitFiles, oldImportEnds, newImportEnds); // } } catch (OperationCanceledException e) { // TODO what to do with cancel? } catch (Exception e) { AntlrCorePlugin.log(e); } } // WORK-IN-PROGRESS -- NON FUNCTIONAL // /** // * Adjust the smap line definitions based on line offsets // * @param compilationUnitFiles the generated java files // * @param oldImportEnds the old location of the "end of imports" marker // * @param newImportEnds the new location of the "end of imports" marker // */ // private void adjustSmapFiles(List compilationUnitFiles, int[] oldImportEnds, int[] newImportEnds) { // int n = 0; // for (Iterator i = compilationUnitFiles.iterator(); i.hasNext(); n++) { // IFile file = (IFile)i.next(); // // skip token type definition files // if (file.getName().endsWith("TokenTypes.java")) // continue; // // IPath smapLocation = file.getLocation().removeFileExtension().addFileExtension(".smap"); // // strip ".java" from the file name and add ".smap" // System.out.println(smapLocation.toFile()); // } // } // // /** // * Determine where the "end of imports" marker in the generated code is // * @param compilationUnitFiles the file to process // * @return an array of line numbers // */ // private int[] findEndOfImports(List compilationUnitFiles) { // int[] endOfImports = new int[compilationUnitFiles.size()]; // int n = 0; // for (Iterator i = compilationUnitFiles.iterator(); i.hasNext(); n++) { // IFile file = (IFile)i.next(); // // skip the token type definitions -- they don't have smaps // if (file.getName().endsWith("TokenTypes.java")) // continue; // // try { // BufferedReader reader = new BufferedReader(new InputStreamReader(file.getContents())); // String line; // while((line = reader.readLine()) != null) { // if (line.startsWith("// $$END-OF-ANTLR-GENERATED-IMPORTS$$")) // break; // endOfImports[n]++; // } // } // catch (Exception e) { // AntlrCorePlugin.log(e); // } // } // return endOfImports; // } /** * Try to get -glib parameter from the first single line comment in given * grammar file (// -glib <super grammar>). * This enables sharing in a team project without local reconfiguration. * @param aFile The grammar file * @return The glib comment */ private String extractGlibComment(IFile aFile) { try { BufferedReader reader = new BufferedReader(new InputStreamReader(aFile.getContents())); // Skip leading white spaces int c = reader.read(); while (c == ' ' || c == '\t' || c == '\n' || c == '\r') { c = reader.read(); } // Match leading "//" if (c == '/' && reader.read() == '/') { // Skip white spaces c = reader.read(); while (c == ' ' || c == '\t') { c = reader.read(); } // Match "-glib" if (c == '-' && reader.read() == 'g' && reader.read() == 'l' && reader.read() == 'i' && reader.read() == 'b' && reader.read() == ' ') { // Skip white spaces c = reader.read(); while (c == ' ' || c == '\t') { c = reader.read(); } // Use rest of line as relative path to super grammar StringBuffer grammar = new StringBuffer(); while (c != '\n' && c != '\r') { grammar.append((char) c); c = reader.read(); } return grammar.toString(); } } } catch (Exception e) { AntlrCorePlugin.log(e); } return null; } }