1 11 package org.eclipse.jdt.internal.debug.eval.ast.engine; 12 13 import java.util.List ; 14 import java.util.Map ; 15 16 import org.eclipse.core.runtime.CoreException; 17 import org.eclipse.core.runtime.IStatus; 18 import org.eclipse.core.runtime.Path; 19 import org.eclipse.core.runtime.Status; 20 import org.eclipse.debug.core.DebugException; 21 import org.eclipse.jdt.core.IClassFile; 22 import org.eclipse.jdt.core.ICompilationUnit; 23 import org.eclipse.jdt.core.IJavaElement; 24 import org.eclipse.jdt.core.IJavaProject; 25 import org.eclipse.jdt.core.JavaCore; 26 import org.eclipse.jdt.core.JavaModelException; 27 import org.eclipse.jdt.core.dom.AST; 28 import org.eclipse.jdt.core.dom.ASTParser; 29 import org.eclipse.jdt.core.dom.CompilationUnit; 30 import org.eclipse.jdt.debug.core.IJavaReferenceType; 31 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin; 32 import org.eclipse.jdt.internal.debug.core.JavaDebugUtils; 33 import org.eclipse.jdt.internal.debug.core.model.JDIReferenceType; 34 35 import com.sun.jdi.AbsentInformationException; 36 import com.sun.jdi.Location; 37 import com.sun.jdi.ReferenceType; 38 39 50 public class EvaluationSourceGenerator { 51 52 private String fCodeSnippet; 53 54 private String [] fLocalVariableTypeNames; 55 private String [] fLocalVariableNames; 56 57 58 private String fSource; 59 private String fCompilationUnitName; 60 private int fSnippetStartPosition; 61 private int fRunMethodStartPosition; 62 private int fRunMethodLength; 63 64 67 public EvaluationSourceGenerator(String [] localVariableTypesNames, String [] localVariableNames, String codeSnippet) { 68 fLocalVariableTypeNames = localVariableTypesNames; 69 fLocalVariableNames = localVariableNames; 70 fCodeSnippet= getCompleteSnippet(codeSnippet); 71 } 72 73 public EvaluationSourceGenerator(String codeSnippet) { 74 this(new String [0], new String [0], codeSnippet); 75 } 76 77 protected String getCompleteSnippet(String codeSnippet) { 78 79 if (isExpression(codeSnippet)) { 80 codeSnippet = "return " + codeSnippet + ';'; } 82 return codeSnippet; 83 } 84 85 92 protected boolean isExpression(String codeSnippet) { 93 boolean inString= false; 94 byte[] chars= codeSnippet.getBytes(); 95 for (int i= 0, numChars= chars.length; i < numChars; i++) { 96 switch (chars[i]) { 97 case '\\': 98 if (inString) { i++; 100 } 101 break; 102 case '\"': 103 case '\'': 104 inString= !inString; 105 break; 106 case ';': 107 if (!inString) { 108 return false; 109 } 110 break; 111 } 112 } 113 return true; 114 } 115 116 public String getCompilationUnitName() { 117 return fCompilationUnitName; 118 } 119 120 public int getSnippetStart() { 121 return fSnippetStartPosition; 122 } 123 public int getRunMethodStart() { 124 return fRunMethodStartPosition; 125 } 126 public int getRunMethodLength() { 127 return fRunMethodLength; 128 } 129 protected void setSnippetStart(int position) { 130 fSnippetStartPosition= position; 131 } 132 protected void setRunMethodStart(int position) { 133 fRunMethodStartPosition= position; 134 } 135 protected void setRunMethodLength(int length) { 136 fRunMethodLength= length; 137 } 138 139 public String getSnippet() { 140 return fCodeSnippet; 141 } 142 143 private void createEvaluationSourceFromSource(String source, String typeName, int position, boolean createInAStaticMethod, IJavaProject project) throws DebugException { 144 ASTParser parser = ASTParser.newParser(AST.JLS3); 145 parser.setSource(source.toCharArray()); 146 Map options=JavaCore.getDefaultOptions(); 147 options.put(JavaCore.COMPILER_COMPLIANCE, project.getOption(JavaCore.COMPILER_COMPLIANCE, true)); 148 String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true); 149 options.put(JavaCore.COMPILER_SOURCE, sourceLevel); 150 parser.setCompilerOptions(options); 151 CompilationUnit unit= (CompilationUnit)parser.createAST(null); 152 SourceBasedSourceGenerator visitor= new SourceBasedSourceGenerator(unit, typeName, position, createInAStaticMethod, fLocalVariableTypeNames, fLocalVariableNames, fCodeSnippet, sourceLevel); 153 unit.accept(visitor); 154 155 if (visitor.hasError()) { 156 throw new DebugException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), IStatus.OK, visitor.getError(), null)); 157 } 158 159 String sourceRes= visitor.getSource(); 160 if (sourceRes == null) { 161 return; 162 } 163 setSource(sourceRes); 164 setCompilationUnitName(visitor.getCompilationUnitName()); 165 setSnippetStart(visitor.getSnippetStart()); 166 setRunMethodStart(visitor.getRunMethodStart()); 167 setRunMethodLength(visitor.getRunMethodLength()); 168 } 169 170 private void createEvaluationSourceFromJDIObject(BinaryBasedSourceGenerator objectToEvaluationSourceMapper) { 171 172 setCompilationUnitName(objectToEvaluationSourceMapper.getCompilationUnitName()); 173 setSnippetStart(objectToEvaluationSourceMapper.getSnippetStart()); 174 setRunMethodStart(objectToEvaluationSourceMapper.getRunMethodStart()); 175 setRunMethodLength(fCodeSnippet.length() + objectToEvaluationSourceMapper.getRunMethodLength()); 176 setSource(objectToEvaluationSourceMapper.getSource().insert(objectToEvaluationSourceMapper.getCodeSnippetPosition(), fCodeSnippet).toString()); 177 } 178 179 private BinaryBasedSourceGenerator getInstanceSourceMapper(JDIReferenceType referenceType, boolean isInStaticMethod, IJavaProject project) { 180 String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true); 181 BinaryBasedSourceGenerator objectToEvaluationSourceMapper = new BinaryBasedSourceGenerator(fLocalVariableTypeNames, fLocalVariableNames, isInStaticMethod, sourceLevel); 182 objectToEvaluationSourceMapper.buildSource(referenceType); 183 return objectToEvaluationSourceMapper; 184 } 185 186 public String getSource(IJavaReferenceType type, IJavaProject javaProject, boolean isStatic) throws CoreException { 187 if (fSource == null) { 188 String baseSource= getTypeSourceFromProject(type, javaProject); 189 int lineNumber= getLineNumber((JDIReferenceType)type); 190 if (baseSource != null && lineNumber != -1) { 191 createEvaluationSourceFromSource(baseSource, type.getName(), lineNumber, isStatic, javaProject); 192 } 193 if (fSource == null) { 194 BinaryBasedSourceGenerator mapper= getInstanceSourceMapper((JDIReferenceType) type, isStatic, javaProject); 195 createEvaluationSourceFromJDIObject(mapper); 196 } 197 } 198 return fSource; 199 } 200 201 private int getLineNumber(JDIReferenceType type) { 202 ReferenceType referenceType= (ReferenceType) type.getUnderlyingType(); 203 try { 204 List allLineLocations = referenceType.allLineLocations(); 205 if (!allLineLocations.isEmpty()) { 206 return ((Location)allLineLocations.get(0)).lineNumber(); 207 } 208 } catch (AbsentInformationException e) { 209 } 210 return -1; 211 } 212 213 protected void setCompilationUnitName(String name) { 214 fCompilationUnitName= name; 215 } 216 217 protected void setSource(String source) { 218 fSource= source; 219 } 220 221 private String getTypeSourceFromProject(IJavaReferenceType type, IJavaProject javaProject) throws CoreException { 222 String [] sourcePaths = type.getSourcePaths(null); 223 IJavaElement element = null; 224 if (sourcePaths != null && sourcePaths.length > 0) { 225 element = javaProject.findElement(new Path(sourcePaths[0])); 226 } else { 227 element = JavaDebugUtils.findElement(type.getName(), javaProject); 229 } 230 return resolveSource(element); 231 } 232 233 239 private String resolveSource(IJavaElement element) throws DebugException { 240 String source= null; 241 try { 242 if (element instanceof IClassFile) { 243 source = ((IClassFile)element).getSource(); 244 } else if (element instanceof ICompilationUnit) { 245 source = ((ICompilationUnit)element).getSource(); 246 } 247 } catch (JavaModelException e) { 248 throw new DebugException(e.getStatus()); 249 } 250 return source; 251 } 252 253 } 254 | Popular Tags |