diff --git a/pdex/.classpath b/pdex/.classpath index 8de404320..eed303dde 100644 --- a/pdex/.classpath +++ b/pdex/.classpath @@ -2,7 +2,6 @@ - diff --git a/pdex/build.xml b/pdex/build.xml index 79cccbda2..21c545ebb 100644 --- a/pdex/build.xml +++ b/pdex/build.xml @@ -72,11 +72,11 @@ - + - + diff --git a/pdex/src/processing/mode/experimental/CompilationChecker.java b/pdex/src/processing/mode/experimental/CompilationChecker.java new file mode 100644 index 000000000..9b7e72a78 --- /dev/null +++ b/pdex/src/processing/mode/experimental/CompilationChecker.java @@ -0,0 +1,584 @@ +package processing.mode.experimental; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.StringTokenizer; + +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.core.compiler.IProblem; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.PackageDeclaration; +import org.eclipse.jdt.core.dom.TypeDeclaration; +import org.eclipse.jdt.internal.compiler.ClassFile; +import org.eclipse.jdt.internal.compiler.CompilationResult; +import org.eclipse.jdt.internal.compiler.Compiler; +import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; +import org.eclipse.jdt.internal.compiler.ICompilerRequestor; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; +import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; +import org.eclipse.jdt.internal.compiler.env.INameEnvironment; +import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; +import org.eclipse.jface.text.Document; + +public class CompilationChecker { + /** + * ICompilationUnit implementation + */ + private class CompilationUnitImpl implements ICompilationUnit { + + private CompilationUnit unit; + + CompilationUnitImpl(CompilationUnit unit) { + this.unit = unit; + } + + public char[] getContents() { + char[] contents = null; + try { + Document doc = new Document(); + if (readFromFile) + doc.set(readFile()); + else + doc.set(sourceText); + // TextEdit edits = unit.rewrite(doc, null); + // edits.apply(doc); + String sourceCode = doc.get(); + if (sourceCode != null) + contents = sourceCode.toCharArray(); + } catch (Exception e) { + throw new RuntimeException(e); + } + return contents; + } + + public char[] getMainTypeName() { + TypeDeclaration classType = (TypeDeclaration) unit.types().get(0); + return classType.getName().getFullyQualifiedName().toCharArray(); + } + + public char[][] getPackageName() { + String[] names = getSimpleNames(this.unit.getPackage().getName() + .getFullyQualifiedName()); + char[][] packages = new char[names.length][]; + for (int i = 0; i < names.length; ++i) + packages[i] = names[i].toCharArray(); + + return packages; + } + + public char[] getFileName() { + TypeDeclaration classType = (TypeDeclaration) unit.types().get(0); + String name = classType.getName().getFullyQualifiedName() + ".java"; + return name.toCharArray(); + } + + @Override + public boolean ignoreOptionalProblems() { + return false; + } + } + + /** + * ICompilerRequestor implementation + */ + private class CompileRequestorImpl implements ICompilerRequestor { + + private List problems; + + private List classes; + + public CompileRequestorImpl() { + this.problems = new ArrayList(); + this.classes = new ArrayList(); + } + + public void acceptResult(CompilationResult result) { + boolean errors = false; + if (result.hasProblems()) { + IProblem[] problems = result.getProblems(); + for (int i = 0; i < problems.length; i++) { + if (problems[i].isError()) + errors = true; + + this.problems.add(problems[i]); + } + } + if (!errors) { + ClassFile[] classFiles = result.getClassFiles(); + for (int i = 0; i < classFiles.length; i++) + this.classes.add(classFiles[i]); + } + } + + List getProblems() { + return this.problems; + } + + List getResults() { + System.out.println("Calling get results"); + return this.classes; + } + } + + /** + * INameEnvironment implementation + */ + private class NameEnvironmentImpl implements INameEnvironment { + + private ICompilationUnit unit; + + private String fullName; + + NameEnvironmentImpl(ICompilationUnit unit) { + this.unit = unit; + this.fullName = CharOperation.toString(this.unit.getPackageName()) + "." + + new String(this.unit.getMainTypeName()); + } + + public NameEnvironmentAnswer findType(char[][] compoundTypeName) { + return findType(CharOperation.toString(compoundTypeName)); + } + + public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) { + String fullName = CharOperation.toString(packageName); + if (typeName != null) { + if (fullName.length() > 0) + fullName += "."; + + fullName += new String(typeName); + } + return findType(fullName); + } + + public boolean isPackage(char[][] parentPackageName, char[] packageName) { + String fullName = CharOperation.toString(parentPackageName); + if (packageName != null) { + if (fullName.length() > 0) + fullName += "."; + + fullName += new String(packageName); + } + if (findType(fullName) != null) + return false; + + try { + return (getClassLoader().loadClass(fullName) == null); + } catch (ClassNotFoundException e) { + return true; + } + } + + public void cleanup() { + } + + private NameEnvironmentAnswer findType(String fullName) { + + if (this.fullName.equals(fullName)) + return new NameEnvironmentAnswer(unit, null); + + try { + InputStream is = getClassLoader().getResourceAsStream(fullName + .replace('.', + '/') + + ".class"); + if (is != null) { + // System.out.println("Find type: " + fullName); + byte[] buffer = new byte[8192]; + int bytes = 0; + ByteArrayOutputStream os = new ByteArrayOutputStream(buffer.length); + while ((bytes = is.read(buffer, 0, buffer.length)) > 0) + os.write(buffer, 0, bytes); + + os.flush(); + ClassFileReader classFileReader = new ClassFileReader( + os.toByteArray(), + fullName + .toCharArray(), + true); + return new NameEnvironmentAnswer(classFileReader, null); + } + return null; + } catch (IOException e) { + throw new RuntimeException(e); + } catch (ClassFormatException e) { + throw new RuntimeException(e); + } + } + } + + private URLClassLoader urlClassLoader; + + private ClassLoader getClassLoader() { + if (urlClassLoader != null) { + return urlClassLoader; + } else { + return getClass().getClassLoader(); + } + } + + private void prepareClassLoader(ArrayList jarList) { + URL urls[] = new URL[jarList.size()]; + for (int i = 0; i < urls.length; i++) { + try { + urls[i] = jarList.get(i).toURI().toURL(); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + urlClassLoader = new URLClassLoader(urls); + System.out.println("URL Classloader ready"); + } + + /** + * ClassLoader implementation + */ + private class CustomClassLoader extends ClassLoader { + + private Map classMap; + + CustomClassLoader(ClassLoader parent, List classesList) { + this.classMap = new HashMap(); + for (int i = 0; i < classesList.size(); i++) { + ClassFile classFile = (ClassFile) classesList.get(i); + String className = CharOperation.toString(classFile.getCompoundName()); + this.classMap.put(className, classFile.getBytes()); + } + } + + public Class findClass(String name) throws ClassNotFoundException { + byte[] bytes = (byte[]) this.classMap.get(name); + if (bytes != null) + return defineClass(name, bytes, 0, bytes.length); + + return super.findClass(name); + } + }; + + private ICompilationUnit generateCompilationUnit() { + ASTParser parser = ASTParser.newParser(AST.JLS4); + try { + parser.setSource("".toCharArray()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Map options = JavaCore.getOptions(); + + // Ben has decided to move on to 1.6. Yay! + JavaCore.setComplianceOptions(JavaCore.VERSION_1_6, options); + parser.setCompilerOptions(options); + CompilationUnit unit = (CompilationUnit) parser.createAST(null); + unit.recordModifications(); + + AST ast = unit.getAST(); + + // Package statement + // package astexplorer; + + PackageDeclaration packageDeclaration = ast.newPackageDeclaration(); + unit.setPackage(packageDeclaration); + // unit.se + packageDeclaration.setName(ast.newSimpleName(fileName)); + // System.out.println("Filename: " + fileName); + // class declaration + // public class SampleComposite extends Composite { + + TypeDeclaration classType = ast.newTypeDeclaration(); + classType.setInterface(false); + // classType.s + classType.setName(ast.newSimpleName(fileName)); + unit.types().add(classType); + // classType.setSuperclass(ast.newSimpleName("Composite")); + return new CompilationUnitImpl(unit); + } + + public static String fileName = "HelloPeasy"; + + public static String readFile() { + BufferedReader reader = null; + System.out.println(fileName); + try { + reader = new BufferedReader( + new InputStreamReader( + new FileInputStream( + new File( + "/media/quarkninja/Work/TestStuff/" + + fileName + + ".java")))); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + StringBuilder ret = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + ret.append(line); + ret.append("\n"); + } + return ("package " + fileName + ";\n" + ret.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + try { + reader.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + return null; + } + + private void compileAndRun(ICompilationUnit unit, boolean runIt) { + + Map settings = new HashMap(); + settings.put(CompilerOptions.OPTION_LineNumberAttribute, + CompilerOptions.GENERATE); + settings.put(CompilerOptions.OPTION_SourceFileAttribute, + CompilerOptions.GENERATE); + + CompilerOptions ops = new CompilerOptions(settings); + + CompileRequestorImpl requestor = new CompileRequestorImpl(); + Compiler compiler = new Compiler(new NameEnvironmentImpl(unit), + DefaultErrorHandlingPolicies + .proceedWithAllProblems(), ops, + requestor, + new DefaultProblemFactory(Locale + .getDefault())); + + compiler.compile(new ICompilationUnit[] { unit }); + // System.out.println(unit.getContents()); + List problems = requestor.getProblems(); + boolean error = false; + for (Iterator it = problems.iterator(); it.hasNext();) { + IProblem problem = (IProblem) it.next(); + StringBuffer buffer = new StringBuffer(); + buffer.append(problem.getMessage()); + buffer.append(" line: "); + buffer.append(problem.getSourceLineNumber()); + String msg = buffer.toString(); + if (problem.isError()) { + error = true; + msg = "Error:\n" + msg + " " + problem.toString(); + } else if (problem.isWarning()) + msg = "Warning:\n" + msg; + + System.out.println(msg); + } + + if (!error && runIt) { + try { + ClassLoader loader = new CustomClassLoader(getClass().getClassLoader(), + requestor.getResults()); + String className = CharOperation.toString(unit.getPackageName()) + "." + + new String(unit.getMainTypeName()); + Class clazz = loader.loadClass(className); + Method m = clazz.getMethod("main", new Class[] { String[].class }); + m.invoke(clazz, new Object[] { new String[0] }); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + private void compileMeQuitely(ICompilationUnit unit, Map compilerSettings) { + + Map settings; + if (compilerSettings == null) { + settings = new HashMap(); + + settings.put(CompilerOptions.OPTION_LineNumberAttribute, + CompilerOptions.GENERATE); + settings.put(CompilerOptions.OPTION_SourceFileAttribute, + CompilerOptions.GENERATE); + settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6); + settings.put(CompilerOptions.OPTION_SuppressWarnings, + CompilerOptions.DISABLED); + // settings.put(CompilerOptions.OPTION_ReportUnusedImport, + // CompilerOptions.IGNORE); + // settings.put(CompilerOptions.OPTION_ReportMissingSerialVersion, + // CompilerOptions.IGNORE); + // settings.put(CompilerOptions.OPTION_ReportRawTypeReference, + // CompilerOptions.IGNORE); + // settings.put(CompilerOptions.OPTION_ReportUncheckedTypeOperation, + // CompilerOptions.IGNORE); + } else { + settings = compilerSettings; + } + + CompilerOptions cop = new CompilerOptions(); + cop.set(settings); + CompileRequestorImpl requestor = new CompileRequestorImpl(); + Compiler compiler = new Compiler(new NameEnvironmentImpl(unit), + DefaultErrorHandlingPolicies + .proceedWithAllProblems(), + settings, requestor, + new DefaultProblemFactory(Locale + .getDefault())); + compiler.compile(new ICompilationUnit[] { unit }); + + List problems = requestor.getProblems(); + prob = new IProblem[problems.size()]; + int count = 0; + for (Iterator it = problems.iterator(); it.hasNext();) { + IProblem problem = (IProblem) it.next(); + prob[count++] = problem; + } + + } + + private void compileMeQuitely(ICompilationUnit unit) { + compileMeQuitely(unit, null); + } + + static private String[] getSimpleNames(String qualifiedName) { + StringTokenizer st = new StringTokenizer(qualifiedName, "."); + ArrayList list = new ArrayList(); + while (st.hasMoreTokens()) { + String name = st.nextToken().trim(); + if (!name.equals("*")) + list.add(name); + } + return (String[]) list.toArray(new String[list.size()]); + } + + public static void main(String[] args) { + ArrayList fl = new ArrayList(); + fl.add(new File( + "/home/quarkninja/Workspaces/processing_workspace/processing/core/library/core.jar")); + CompilationChecker cc = new CompilationChecker(fl); + cc.getErrors("Brightness"); + cc.display(); + } + + public void display() { + boolean error = false; + int errorCount = 0, warningCount = 0, count = 0; + for (int i = 0; i < prob.length; i++) { + IProblem problem = prob[i]; + if (problem == null) + continue; + StringBuffer buffer = new StringBuffer(); + buffer.append(problem.getMessage()); + buffer.append(" | line: "); + buffer.append(problem.getSourceLineNumber()); + String msg = buffer.toString(); + if (problem.isError()) { + error = true; + msg = "Error: " + msg; + errorCount++; + } else if (problem.isWarning()) { + msg = "Warning: " + msg; + warningCount++; + } + System.out.println(msg); + prob[count++] = problem; + } + + if (!error) { + System.out.println("===================================="); + System.out.println(" Compiled without any errors. "); + System.out.println("===================================="); + } else { + System.out.println("===================================="); + System.out.println(" Compilation failed. You erred man! "); + System.out.println("===================================="); + + } + System.out.print("Total warnings: " + warningCount); + System.out.println(", Total errors: " + errorCount); + } + + IProblem[] prob; + + public IProblem[] getErrors(String name) { + fileName = name; + compileMeQuitely(generateCompilationUnit()); + // System.out.println("getErrors()"); + + return prob; + } + + public IProblem[] getErrors(String sourceName, String source, Map settings, + URLClassLoader classLoader) { + fileName = sourceName; + readFromFile = false; + sourceText = "package " + fileName + ";\n" + source; + if (classLoader != null) + this.urlClassLoader = classLoader; + compileMeQuitely(generateCompilationUnit(), settings); + // System.out.println("getErrors(), Done."); + +// if (prob.length > 0) { +// Object[][] data = new Object[prob.length][10]; +// for (int i = 0; i < data.length; i++) { +// IProblem p = prob[i]; +// // data[i] = new +// // Object[]{p.getMessage(),p.getSourceLineNumber(),p.isError(),p}; +// data[i] = new Object[] { p.getOriginatingFileName(), +// p.getMessage(), p.getID(), p.getArguments(), 0, +// p.getSourceStart(), p.getSourceEnd(), +// p.getSourceLineNumber(), p.isError(), p.isWarning() }; +// +// } +// +// return data; +// } + return prob; + } + + private boolean readFromFile = true; + + String sourceText = ""; + + public IProblem[] getErrors(String sourceName, String source) { + return getErrors(sourceName, source, null); + } + + @SuppressWarnings("rawtypes") + public IProblem[] getErrors(String sourceName, String source, Map settings) { + fileName = sourceName; + readFromFile = false; + sourceText = "package " + fileName + ";\n" + source; + + compileMeQuitely(generateCompilationUnit(), settings); + // System.out.println("getErrors(), Done."); + return prob; + } + + public CompilationChecker() { + // System.out.println("Compilation Checker initialized."); + } + + public CompilationChecker(ArrayList fileList) { + prepareClassLoader(fileList); + // System.out.println("Compilation Checker initialized."); + } +} diff --git a/pdex/src/processing/mode/experimental/DebugEditor.java b/pdex/src/processing/mode/experimental/DebugEditor.java index 8db5b9ac1..8d1f83368 100755 --- a/pdex/src/processing/mode/experimental/DebugEditor.java +++ b/pdex/src/processing/mode/experimental/DebugEditor.java @@ -657,9 +657,6 @@ public class DebugEditor extends JavaEditor implements ActionListener { }); debugMenu.add(debugMessagesEnabled); - showOutline = Toolkit.newJMenuItem("Show Outline", KeyEvent.VK_L); - showOutline.addActionListener(this); - debugMenu.add(showOutline); writeErrorLog = new JCheckBoxMenuItem("Write Errors to Log"); writeErrorLog.setSelected(ExperimentalMode.errorLogsEnabled); @@ -683,6 +680,10 @@ public class DebugEditor extends JavaEditor implements ActionListener { }); debugMenu.add(jitem); */ + showOutline = Toolkit.newJMenuItem("Show Outline", KeyEvent.VK_L); + showOutline.addActionListener(this); + debugMenu.add(showOutline); + return debugMenu; } diff --git a/pdex/src/processing/mode/experimental/ErrorCheckerService.java b/pdex/src/processing/mode/experimental/ErrorCheckerService.java index 9e95c4f9d..dbaba3d94 100644 --- a/pdex/src/processing/mode/experimental/ErrorCheckerService.java +++ b/pdex/src/processing/mode/experimental/ErrorCheckerService.java @@ -165,7 +165,7 @@ public class ErrorCheckerService implements Runnable{ /** * Compilation Checker object. */ - protected Object compilationChecker; + protected CompilationChecker compilationChecker; /** @@ -619,107 +619,47 @@ public class ErrorCheckerService implements Runnable{ // If imports have changed, reload classes with new classpath. if (loadCompClass) { - // if (classpathJars.size() > 0) - // System.out - // .println("Experimental Mode: Loading contributed libraries referenced by import statements."); - - // The folder SketchBook/modes/ExperimentalMode/mode - File f = editor.getMode().getContentFile("mode"); - - if(!f.exists()) { - System.err.println("Could not locate the files required for on-the-fly error checking. Bummer."); - return; - } - - FileFilter fileFilter = new FileFilter() { - public boolean accept(File file) { - return (file.getName().endsWith(".jar") && !file - .getName().startsWith(editor.getMode().getClass().getSimpleName())); - } - }; - - File[] jarFiles = f.listFiles(fileFilter); - // log( "Jar files found? " + (jarFiles != null)); - //for (File jarFile : jarFiles) { - //classpathJars.add(jarFile.toURI().toURL()); - //} - - classpath = new URL[classpathJars.size() + jarFiles.length]; + classpath = new URL[classpathJars.size()]; int ii = 0; for (; ii < classpathJars.size(); ii++) { classpath[ii] = classpathJars.get(ii); } - for (int i = 0; i < jarFiles.length; i++) { - classpath[ii++] = jarFiles[i].toURI().toURL(); - } compilationChecker = null; - checkerClass = null; classLoader = null; System.gc(); // log("CP Len -- " + classpath.length); classLoader = new URLClassLoader(classpath); - // log("1."); - checkerClass = Class.forName("CompilationChecker", true, - classLoader); - // log("2."); - compilationChecker = checkerClass.newInstance(); - + compilationChecker = new CompilationChecker(); loadCompClass = false; } if (compilerSettings == null) { prepareCompilerSetting(); } - Method getErrors = checkerClass.getMethod("getErrorsAsObjArr", - new Class[] { String.class, String.class, Map.class }); - - Object[][] errorList = (Object[][]) getErrors - .invoke(compilationChecker, className, sourceCode, - compilerSettings); - - if (errorList == null) { - return; - } synchronized (problemsList) { - problems = new DefaultProblem[errorList.length]; + problems = compilationChecker.getErrors(className, sourceCode, compilerSettings, classLoader); + if (problems == null) { + return; + } + + for (int i = 0; i < problems.length; i++) { - for (int i = 0; i < errorList.length; i++) { - - // for (int j = 0; j < errorList[i].length; j++) - // System.out.print(errorList[i][j] + ", "); - - problems[i] = new DefaultProblem((char[]) errorList[i][0], - (String) errorList[i][1], - ((Integer) errorList[i][2]).intValue(), - (String[]) errorList[i][3], - ((Integer) errorList[i][4]).intValue(), - ((Integer) errorList[i][5]).intValue(), - ((Integer) errorList[i][6]).intValue(), - ((Integer) errorList[i][7]).intValue() - 1, 0); + IProblem problem = problems[i]; + // added a -1 to line number because in compile check code // an extra package statement is added, so all line numbers // are increased by 1 - - // System.out - // .println("ECS: " + problems[i].getMessage() + "," - // + problems[i].isError() + "," - // + problems[i].isWarning()); - - IProblem problem = problems[i]; - // log(problem.getMessage()); - // for (String j : problem.getArguments()) { - // log("arg " + j); - // } - int a[] = calculateTabIndexAndLineNumber(problem.getSourceLineNumber()); + int a[] = calculateTabIndexAndLineNumber(problem.getSourceLineNumber() - 1); + Problem p = new Problem(problem, a[0], a[1]); - if ((Boolean) errorList[i][8]) { + if (problem.isError()) { p.setType(Problem.ERROR); containsErrors.set(true); // set flag } - if ((Boolean) errorList[i][9]) { + if (problem.isWarning()) { p.setType(Problem.WARNING); } @@ -730,15 +670,9 @@ public class ErrorCheckerService implements Runnable{ problemsList.add(p); } } - } catch (ClassNotFoundException e) { - System.err.println("Compiltation Checker files couldn't be found! " - + e + " compileCheck() problem."); - pauseThread(); - } catch (MalformedURLException e) { - System.err.println("Compiltation Checker files couldn't be found! " - + e + " compileCheck() problem."); - pauseThread(); - } catch (Exception e) { + } + + catch (Exception e) { System.err.println("compileCheck() problem." + e); e.printStackTrace(); pauseThread(); @@ -793,7 +727,8 @@ public class ErrorCheckerService implements Runnable{ .getIProblem().getSourceEnd() - pkgNameOffset; log(p.toString()); log("IProblem Start " + prbStart + ", End " + prbEnd); - int javaLineNumber = p.getIProblem().getSourceLineNumber() - 1; + int javaLineNumber = p.getSourceLineNumber() + - ((compilationUnitState != 2) ? 1 : 2); Element lineElement = javaSource.getDefaultRootElement() .getElement(javaLineNumber); if (lineElement == null) { diff --git a/pdex/src/processing/mode/experimental/Problem.java b/pdex/src/processing/mode/experimental/Problem.java index d46aa254f..6fa029188 100644 --- a/pdex/src/processing/mode/experimental/Problem.java +++ b/pdex/src/processing/mode/experimental/Problem.java @@ -129,6 +129,16 @@ public class Problem { public int getLineNumber(){ return lineNumber; } + + /** + * Remember to subtract a -1 to line number because in compile check code an + * extra package statement is added, so all line numbers are increased by 1 + * + * @return + */ + public int getSourceLineNumber(){ + return iProblem.getSourceLineNumber(); + } public void setType(int ProblemType){ if(ProblemType == ERROR)