- Timestamp:
- Jul 5, 2010 3:57:08 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagnoliaPlugin/src/org/magnolialang/manager/MagnoliaProjectManager.java
r448 r452 10 10 import org.eclipse.core.resources.IFile; 11 11 import org.eclipse.core.resources.IMarker; 12 import org.eclipse.core.resources.IProject; 12 13 import org.eclipse.core.resources.IResource; 14 import org.eclipse.core.resources.ResourcesPlugin; 13 15 import org.eclipse.core.runtime.CoreException; 14 16 import org.eclipse.core.runtime.Path; … … 17 19 import org.eclipse.imp.pdb.facts.ISourceLocation; 18 20 import org.eclipse.imp.utils.Pair; 19 import org.magnolialang.eclipse.MagnoliaPlugin;20 21 import org.magnolialang.eclipse.editor.ImplementationError; 21 import org.magnolialang.eclipse.editor.ParseController;22 22 import org.magnolialang.env.MagnoliaEnvironment; 23 23 import org.magnolialang.errors.CompilationError; … … 29 29 import org.magnolialang.programs.MagnoliaAdapter; 30 30 import org.magnolialang.xatree.CxxSkin; 31 import org.magnolialang.xatree.TreeImploder;32 31 import org.magnolialang.xatree.XaTreeAdapter; 33 import org.rascalmpl.values.uptr.ParsetreeAdapter;34 32 33 /** 34 * @author anya 35 * 36 */ 35 37 @SuppressWarnings("deprecation") 36 public class MagnoliaProjectManager implements IProjectManager{38 public class MagnoliaProjectManager { 37 39 private static Map<String, MagnoliaProjectManager> managerMap; 38 39 private ModuleLoader loader; 40 private IBuildPath buildPath; 41 private ISourceProject project; 42 private Map<String, ModuleInfo> moduleMap; 43 private Map<URI, String> uriMap; 44 private Map<ParseController, ModuleInfo> ctrlMap; 40 protected final IProject project; 41 protected final ModuleLoader loader; 42 protected final IBuildPath buildPath; 43 protected final Map<String, MagnoliaModuleInfo> moduleMap; 44 protected final Map<URI, String> uriMap; 45 45 46 public MagnoliaProjectManager(I SourceProject project) {46 public MagnoliaProjectManager(IProject project) { 47 47 this.project = project; 48 48 this.loader = new ModuleLoader(this); 49 49 this.buildPath = new MagnoliaBuildPath(null); 50 50 if(project != null) 51 this.buildPath.addPath(ProjectURIResolver.constructProjectURI(project , new Path("")));52 this.moduleMap = new HashMap<String, M oduleInfo>();51 this.buildPath.addPath(ProjectURIResolver.constructProjectURI(project.getName(), new Path(""))); 52 this.moduleMap = new HashMap<String, MagnoliaModuleInfo>(); 53 53 this.uriMap = new HashMap<URI, String>(); 54 this.ctrlMap = new IdentityHashMap<ParseController, ModuleInfo>();55 54 } 56 55 57 public static MagnoliaProjectManager getProjectManager( ISourceProjectproject) {56 public static MagnoliaProjectManager getProjectManager(String project) { 58 57 if(managerMap == null) 59 58 managerMap = new HashMap<String, MagnoliaProjectManager>(); 60 if(managerMap.containsKey(project .getName()))61 return managerMap.get(project .getName());59 if(managerMap.containsKey(project)) 60 return managerMap.get(project); 62 61 else { 63 MagnoliaProjectManager manager = new MagnoliaProjectManager( project);64 managerMap.put(project .getName(), manager);62 MagnoliaProjectManager manager = new MagnoliaProjectManager(ResourcesPlugin.getWorkspace().getRoot().getProject(project)); 63 managerMap.put(project, manager); 65 64 return manager; 66 65 } 67 66 } 68 67 68 public static MagnoliaProjectManager getProjectManager(IProject project) { 69 return getProjectManager(project.getName()); 70 } 71 72 public static MagnoliaProjectManager getProjectManager(ISourceProject project) { 73 return getProjectManager(project.getName()); 74 } 75 69 76 public void createModule(String moduleName, IConstructor moduleTree) { 70 77 … … 72 79 73 80 public void createModule(String moduleName, String sourceModuleName, IConstructor moduleTree) { 74 M oduleInfo srcInfo = getModuleInfo(sourceModuleName);75 ModuleInfo info =moduleMap.get(moduleName);81 MagnoliaModuleInfo srcInfo = (MagnoliaModuleInfo) getModule(sourceModuleName); 82 FileModuleInfo info = (FileModuleInfo) moduleMap.get(moduleName); 76 83 URI uri = srcInfo.dir.resolve(moduleName.replace('.', '/') + ".mg"); 77 84 if(info == null) { 78 info = new ModuleInfo(); 79 info.moduleName = moduleName; 80 info.uri = uri; 85 info = new FileModuleInfo(this, moduleName, uri, srcInfo.dir); 81 86 } 82 87 else if(!info.uri.equals(uri)) … … 84 89 85 90 moduleTree = MagnoliaAdapter.setModuleName(moduleTree, moduleName); 86 info.dir = srcInfo.dir; // should be same87 info.tree = moduleTree;88 info.parseTree = null;89 91 String result = XaTreeAdapter.yield(moduleTree, new CxxSkin(), true); 90 92 if(result != null) { 91 try { 92 IFile file = ProjectURIResolver.getFile(info.uri); 93 94 if(file.exists()) 95 file.setContents(new StringBufferInputStream(result), false, true, null); 96 else 97 file.create(new StringBufferInputStream(result), false, null); 98 99 info.file = file; 100 } catch (Exception e) { 101 throw new ImplementationError("Error creating module " + moduleName, e); 102 } 93 info.setContents(result); 94 info.tree = moduleTree; 95 info.parseTree = null; 103 96 } 104 97 } 105 98 106 99 public MagnoliaEnvironment getModuleEnv(String moduleName) { 107 if(moduleMap.containsKey(moduleName)) { 108 ModuleInfo info = moduleMap.get(moduleName); 109 if(info.tree == null) 110 getModuleTree(moduleName); 111 if(info.env == null) { 112 info.env = new MagnoliaEnvironment(); 113 try { 114 loader.loadModule(info.tree, info.env); 115 } catch (IOException e) { 116 info.env = null; 117 e.printStackTrace(); 118 } 119 } 120 return info.env; 121 } 122 else 123 return null; 100 return getModule(moduleName).getEnv(); 124 101 } 102 125 103 public MagnoliaEnvironment getModuleEnv(URI uri) { 126 104 return getModuleEnv(getModuleName(uri)); 127 105 } 128 106 129 public IConstructor getModuleTree(String moduleName) {130 return getModuleTree(moduleName, false);131 }132 133 107 public IConstructor getModuleTree(URI uri) { 134 108 return getModuleTree(getModuleName(uri)); 135 109 } 136 110 137 public IConstructor getModuleTree(String moduleName, boolean loadFromEditor) { 138 ModuleInfo info = getModuleInfo(moduleName); 139 if(info.tree == null || info.isModified() || (loadFromEditor && info.parseTreeHasChanged())) { 140 info.loadTree(true); 141 } 142 return info.tree; 143 111 public IConstructor getModuleTree(String moduleName) { 112 return getModule(moduleName).getTree(); 144 113 } 145 114 146 private ModuleInfo getModuleInfo(String moduleName) { 115 /** 116 * @param moduleName 117 * @return Module info for the module (never null) 118 */ 119 public IModuleInfo getModule(String moduleName) { 147 120 if(moduleMap.containsKey(moduleName)) { 148 121 return moduleMap.get(moduleName); 149 122 } 150 123 else { 151 ModuleInfo info = new ModuleInfo(); 152 info.uri = buildPath.find(moduleName); 153 if(info.uri == null) 154 throw new ModuleNotFoundError(moduleName); 155 info.dir = buildPath.getModuleName(info.uri).first; 156 info.moduleName = moduleName; 124 MagnoliaModuleInfo info = new FileModuleInfo(this, moduleName); 125 moduleMap.put(moduleName, info); 157 126 return info; 158 127 } … … 165 134 return name; 166 135 } 136 137 public String getModuleName(IFile file) { 138 return getModuleName(ProjectURIResolver.constructProjectURI(file.getProject().getName(), file.getProjectRelativePath())); 139 } 167 140 168 public I SourceProject getProject() {141 public IProject getProject() { 169 142 return project; 170 143 } 171 144 172 public void addEditedModule(ParseController ctrl) {173 ModuleInfo info = new ModuleInfo();174 info.ctrl = ctrl;175 info.file = ctrl.getProject().getRawProject().getFile(ctrl.getPath());176 info.uri = ProjectURIResolver.constructProjectURI(ctrl.getProject(), ctrl.getPath());177 Pair<URI, String> tmp = buildPath.getModuleName(info.uri);178 info.dir = tmp.first;179 info.moduleName = tmp.second;180 if(info.moduleName != null) {181 moduleMap.put(info.moduleName, info);182 uriMap.put(info.uri, info.moduleName);183 }184 ctrlMap.put(ctrl, info);185 }186 187 public void removeEditedModule(ParseController ctrl) {188 // TODO: Handle multiple editors for same module189 ModuleInfo info = ctrlMap.get(ctrl);190 if(info != null) {191 ModuleInfo info2 = moduleMap.get(info.moduleName);192 if(info2 == info) {193 moduleMap.remove(info.moduleName);194 uriMap.remove(info.uri);195 }196 else if(info2 != null && info2.ctrl == ctrl) {197 info2.ctrl = null;198 }199 ctrlMap.remove(ctrl);200 }201 }202 203 public String findEditedModule(ParseController ctrl) {204 // TODO: Handle multiple editors for same module205 ModuleInfo info = ctrlMap.get(ctrl);206 if(info != null) {207 ModuleInfo info2 = moduleMap.get(info.moduleName);208 if(info2 != info)209 throw new ImplementationError("Find-by-controller does not match find-by-name");210 return info.moduleName;211 }212 else213 return null;214 }215 216 145 public boolean dataInvariant() { 217 146 return loader != null && buildPath != null; 218 147 } 219 148 220 protected class ModuleInfo { 221 long modStamp; 222 ParseController ctrl; 223 IConstructor tree; 224 IConstructor parseTree; 225 URI uri; 226 URI dir; 227 IFile file; 228 String moduleName; 229 MagnoliaEnvironment env; 230 231 boolean loadTree(boolean force) { 232 env = null; 233 modStamp = IResource.NULL_STAMP; 234 235 if(ctrl != null && ctrl.getCurrentAst() != null) { 236 parseTree = ctrl.getCurrentAst(); 237 modStamp = file.getModificationStamp(); 238 } 239 else if(force) { 240 modStamp = MagnoliaPlugin.getResolverRegistry().lastModified(uri); 241 parseTree = loader.parseModule(uri); 242 } 243 244 245 if(parseTree != null) { 246 tree = (IConstructor) TreeImploder.implodeTree(ParsetreeAdapter.getTop(parseTree)); 247 if(file != null) 248 try { 249 file.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE); 250 } catch (CoreException e) {} 251 return true; 252 } 253 else { 254 tree = null; 255 return false; 256 } 257 } 258 259 boolean parseTreeHasChanged() { 260 return ctrl != null && ctrl.getCurrentAst() != parseTree; 261 } 262 263 boolean isModified() { 264 return (file != null && file.getModificationStamp() != modStamp) || 265 (uri != null && MagnoliaPlugin.getResolverRegistry().lastModified(uri) != modStamp); 266 } 149 public void reportError(CompilationError ce) { 150 reportError(ce, null); 267 151 } 268 269 public void reportError(CompilationError ce) { 152 public void reportError(CompilationError ce, String prefix) { 270 153 ISourceLocation loc = ce.getLocation(); 271 154 if(loc != null) { 155 if(prefix == null) 156 prefix = ""; 157 else 158 prefix = prefix + ": "; 272 159 URI uri = loc.getURI(); 273 274 160 IFile file = ProjectURIResolver.getFile(uri); 275 161 try { 276 IMarker marker = file.createMarker(IMarker.PROBLEM); 277 marker.setAttribute(IMarker.CHAR_START, loc.getOffset()); 278 marker.setAttribute(IMarker.CHAR_END, loc.getOffset()+loc.getLength()); 279 marker.setAttribute(IMarker.MESSAGE, ce.getMarkerMessage()); 162 int start = loc.getOffset(); 163 int end = loc.getOffset()+loc.getLength(); 164 for(IMarker m : file.findMarkers(ce.getMarkerType(), false, IResource.DEPTH_INFINITE)) { 165 if(m.getAttribute(IMarker.CHAR_START, -1) == start 166 && m.getAttribute(IMarker.CHAR_END, -1) == end 167 && m.getAttribute(IMarker.MESSAGE, "").equals(prefix + ce.getMarkerMessage())); 168 return; 169 } 170 IMarker marker = file.createMarker(ce.getMarkerType()); 171 marker.setAttribute(IMarker.CHAR_START, start); 172 marker.setAttribute(IMarker.CHAR_END, end); 173 marker.setAttribute(IMarker.MESSAGE, prefix + ce.getMarkerMessage()); 280 174 marker.setAttribute(IMarker.LOCATION, "Line " + loc.getBeginLine() + ", column " + loc.getBeginColumn()); 281 175 marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); … … 288 182 } 289 183 184 public Object getImports(String moduleName) { 185 MagnoliaEnvironment env = getModuleEnv(moduleName); 186 return null; 187 } 188 290 189 }
Note:
See TracChangeset
for help on using the changeset viewer.