001 package org.meta_environment.eclipse.parser; 002 003 import java.util.Iterator; 004 005 import org.eclipse.core.resources.IFile; 006 import org.eclipse.core.runtime.IPath; 007 import org.eclipse.core.runtime.IProgressMonitor; 008 import org.eclipse.imp.language.ILanguageService; 009 import org.eclipse.imp.language.Language; 010 import org.eclipse.imp.language.LanguageRegistry; 011 import org.eclipse.imp.model.ISourceProject; 012 import org.eclipse.imp.parser.ILexer; 013 import org.eclipse.imp.parser.IMessageHandler; 014 import org.eclipse.imp.parser.IParseController; 015 import org.eclipse.imp.parser.IParser; 016 import org.eclipse.imp.parser.ISourcePositionLocator; 017 import org.eclipse.imp.services.IAnnotationTypeInfo; 018 import org.eclipse.imp.services.ILanguageSyntaxProperties; 019 import org.eclipse.jface.text.IRegion; 020 import org.meta_environment.eclipse.Activator; 021 import org.meta_environment.eclipse.tokens.TokenIterator; 022 import org.meta_environment.eclipse.tokens.TokenLocator; 023 024 import toolbus.adapter.eclipse.EclipseTool; 025 import aterm.ATerm; 026 import aterm.ATermAppl; 027 import aterm.ATermList; 028 import errorapi.Factory; 029 import errorapi.types.Area; 030 import errorapi.types.Error; 031 import errorapi.types.ErrorList; 032 import errorapi.types.Subject; 033 034 public class ParseController extends EclipseTool implements IParseController, 035 ILanguageService { 036 037 private IPath filePath; 038 039 private String absPath; 040 041 private ISourceProject project; 042 043 private IMessageHandler handler; 044 045 private ErrorList errors; 046 047 public ATerm result; 048 049 Factory eFactory; 050 051 public ParseController() { 052 super("parse-controller"); 053 eFactory = Factory.getInstance(factory); 054 055 // Hack to make sure the other tools are loaded 056 // one parse request can trigger a snd-eval to another 057 // tool (like the build tool) which has not connected 058 // yet. The eclipse initialization routine is single-threaded, 059 // such that this results in a deadlock. Another cause is 060 // that the editors which are part of the workbench are 061 // initialized before the earlyStartup methods are called. 062 Activator.getInstance().earlyStartup(); 063 } 064 065 public IAnnotationTypeInfo getAnnotationTypeInfo() { 066 return null; 067 } 068 069 public Object getCurrentAst() { 070 return result; 071 } 072 073 public ILexer getLexer() { 074 return null; 075 } 076 077 public ISourcePositionLocator getNodeLocator() { 078 return new TokenLocator(); 079 } 080 081 public IParser getParser() { 082 return null; 083 } 084 085 public IPath getPath() { 086 return filePath; 087 } 088 089 public ISourceProject getProject() { 090 return project; 091 } 092 093 public ILanguageSyntaxProperties getSyntaxProperties() { 094 // TODO Auto-generated method stub 095 return null; 096 } 097 098 public void initialize(IPath filePath, ISourceProject project, IMessageHandler handler) { 099 this.filePath = filePath; 100 this.project = project; 101 this.handler = handler; 102 103 connect(); // NOTE: This may only be called once. 104 105 // try to make path absolute 106 IFile file = project.getRawProject().getFile(filePath); 107 108 if (file.exists()) { 109 absPath = file.getLocation().toOSString(); 110 } else { 111 absPath = filePath.toOSString(); 112 } 113 } 114 115 public Object parse(String input, boolean scanOnly, IProgressMonitor monitor) { 116 String l = this.getLanguage().getName(); 117 118 ATermAppl response = sendRequest(factory.make("parse(<str>,<str>,<str>)", l, absPath, input)); 119 ATerm res = response.getArgument(0); 120 121 if (res.getType() == ATerm.APPL) { 122 ATermAppl appl = (ATermAppl) res; 123 String name = appl.getName(); 124 125 if (name.equals(TIME_OUT)) { 126 result = null; 127 errors = null; 128 return null; 129 } else if (name.equals("correct")) { 130 result = appl.getArgument(0); 131 errors = null; 132 return result; 133 } else if (name.equals("error")) { 134 result = null; 135 errors = eFactory.SummaryFromTerm(appl.getArgument(0)).getList(); 136 handleErrors(errors); 137 return null; 138 } 139 } 140 141 return result; 142 } 143 144 private void handleErrors(ErrorList list) { 145 for (; !list.isEmpty(); list = list.getTail()) { 146 Error error = list.getHead(); 147 Subject subject = error.getList().getHead(); 148 Area area; 149 150 if (subject.hasLocation()) { 151 area = subject.getLocation().getArea(); 152 } else { 153 area = eFactory.makeArea_Area(0, 0, 0, 0, 0, 0); 154 } 155 156 handler.handleSimpleMessage(error.getDescription() + ": " 157 + subject.getDescription(), area.getOffset(), area 158 .getOffset() 159 + area.getLength(), area.getBeginColumn(), area 160 .getEndColumn(), area.getBeginLine(), area.getEndLine()); 161 } 162 } 163 164 public Iterator<?> getTokenIterator(IRegion region) { 165 if (result != null) { 166 ATermAppl response = sendRequest(factory.make("highlight(<term>)", result)); 167 ATerm ack = response.getArgument(0); 168 169 if (ack instanceof ATermList) { 170 ATermList slices = (ATermList) ack; 171 return new TokenIterator(eFactory, slices); 172 } 173 // timeout happened 174 } 175 176 return new TokenIterator(eFactory, factory.makeList()); 177 } 178 179 public Language getLanguage() { 180 return LanguageRegistry.findLanguage(filePath, null); 181 } 182 }