/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.core.tests.performance; import java.io.PrintStream; import java.text.NumberFormat; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import junit.framework.*; import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.dom.*; import org.eclipse.jdt.core.tests.model.AbstractJavaModelTests; /** */ @SuppressWarnings({"rawtypes", "unchecked"}) public class FullSourceWorkspaceASTTests extends FullSourceWorkspaceTests { /** * Internal synonym for deprecated constant AST.JSL3 * to alleviate deprecation warnings. * @deprecated */ /*package*/ static final int JLS3_INTERNAL = AST.JLS3; // Tests counter private static int TESTS_COUNT = 0; private final static int ITERATIONS_COUNT = 10; int nodesCount = 0; // Log files private static PrintStream[] LOG_STREAMS = new PrintStream[DIM_NAMES.length]; /** * @param name */ public FullSourceWorkspaceASTTests(String name) { super(name); } static { // TESTS_PREFIX = "testDomAstCreationJLS2"; } public static Test suite() { Test suite = buildSuite(testClass()); TESTS_COUNT = suite.countTestCases(); createPrintStream(testClass(), LOG_STREAMS, TESTS_COUNT, null); return suite; } private static Class testClass() { return FullSourceWorkspaceASTTests.class; } protected void setUp() throws Exception { AbstractJavaModelTests.waitUntilIndexesReady(); super.setUp(); } /* (non-Javadoc) * @see junit.framework.TestCase#tearDown() */ protected void tearDown() throws Exception { // End of execution => one test less TESTS_COUNT--; // Log perf result if (LOG_DIR != null) { logPerfResult(LOG_STREAMS, TESTS_COUNT); } // Print statistics if (TESTS_COUNT == 0) { System.out.println("-------------------------------------"); System.out.println("DOM/AST creation performance test statistics:"); NumberFormat intFormat = NumberFormat.getIntegerInstance(); System.out.println(" - "+intFormat.format(this.nodesCount)+" nodes have been parsed."); System.out.println("-------------------------------------\n"); } // Call super at the end as it close print streams super.tearDown(); } /** * Comment Mapper visitor */ class CommentMapperASTVisitor extends ASTVisitor { CompilationUnit compilationUnit; int nodes = 0; int extendedStartPositions = 0; int extendedEndPositions = 0; public CommentMapperASTVisitor(CompilationUnit unit) { this.compilationUnit = unit; } protected boolean visitNode(ASTNode node) { // get node positions and extended positions int nodeStart = node.getStartPosition(); int nodeEnd = node.getLength() - 1 - nodeStart; int extendedStart = this.compilationUnit.getExtendedStartPosition(node); int extendedEnd = this.compilationUnit.getExtendedLength(node) - 1 - extendedStart; // update counters if (extendedStart < nodeStart) this.extendedStartPositions++; if (extendedEnd > nodeEnd) this.extendedEndPositions++; this.nodes++; return true; } protected void endVisitNode(ASTNode node) { // do nothing } public boolean visit(AnonymousClassDeclaration node) { return visitNode(node); } public boolean visit(ArrayAccess node) { return visitNode(node); } public boolean visit(ArrayCreation node) { return visitNode(node); } public boolean visit(ArrayInitializer node) { return visitNode(node); } public boolean visit(ArrayType node) { visitNode(node); return false; } public boolean visit(AssertStatement node) { return visitNode(node); } public boolean visit(Assignment node) { return visitNode(node); } public boolean visit(Block node) { return visitNode(node); } public boolean visit(BooleanLiteral node) { return visitNode(node); } public boolean visit(BreakStatement node) { return visitNode(node); } public boolean visit(CastExpression node) { return visitNode(node); } public boolean visit(CatchClause node) { return visitNode(node); } public boolean visit(CharacterLiteral node) { return visitNode(node); } public boolean visit(ClassInstanceCreation node) { return visitNode(node); } public boolean visit(CompilationUnit node) { return visitNode(node); } public boolean visit(ConditionalExpression node) { return visitNode(node); } public boolean visit(ConstructorInvocation node) { return visitNode(node); } public boolean visit(ContinueStatement node) { return visitNode(node); } public boolean visit(DoStatement node) { return visitNode(node); } public boolean visit(EmptyStatement node) { return visitNode(node); } public boolean visit(ExpressionStatement node) { return visitNode(node); } public boolean visit(FieldAccess node) { return visitNode(node); } public boolean visit(FieldDeclaration node) { return visitNode(node); } public boolean visit(ForStatement node) { return visitNode(node); } public boolean visit(IfStatement node) { return visitNode(node); } public boolean visit(ImportDeclaration node) { return visitNode(node); } public boolean visit(InfixExpression node) { return visitNode(node); } public boolean visit(InstanceofExpression node) { return visitNode(node); } public boolean visit(Initializer node) { return visitNode(node); } public boolean visit(Javadoc node) { // do not visit Javadoc tags by default. Use constructor with // boolean to enable. if (super.visit(node)) { return visitNode(node); } return false; } public boolean visit(LabeledStatement node) { return visitNode(node); } public boolean visit(MethodDeclaration node) { return visitNode(node); } public boolean visit(MethodInvocation node) { return visitNode(node); } public boolean visit(NullLiteral node) { return visitNode(node); } public boolean visit(NumberLiteral node) { return visitNode(node); } public boolean visit(PackageDeclaration node) { return visitNode(node); } public boolean visit(ParenthesizedExpression node) { return visitNode(node); } public boolean visit(PostfixExpression node) { return visitNode(node); } public boolean visit(PrefixExpression node) { return visitNode(node); } public boolean visit(PrimitiveType node) { return visitNode(node); } public boolean visit(QualifiedName node) { return visitNode(node); } public boolean visit(ReturnStatement node) { return visitNode(node); } public boolean visit(SimpleName node) { return visitNode(node); } public boolean visit(SimpleType node) { return visitNode(node); } public boolean visit(StringLiteral node) { return visitNode(node); } public boolean visit(SuperConstructorInvocation node) { return visitNode(node); } public boolean visit(SuperFieldAccess node) { return visitNode(node); } public boolean visit(SuperMethodInvocation node) { return visitNode(node); } public boolean visit(SwitchCase node) { return visitNode(node); } public boolean visit(SwitchStatement node) { return visitNode(node); } public boolean visit(SynchronizedStatement node) { return visitNode(node); } public boolean visit(ThisExpression node) { return visitNode(node); } public boolean visit(ThrowStatement node) { return visitNode(node); } public boolean visit(TryStatement node) { return visitNode(node); } public boolean visit(TypeDeclaration node) { return visitNode(node); } public boolean visit(TypeDeclarationStatement node) { return visitNode(node); } public boolean visit(TypeLiteral node) { return visitNode(node); } public boolean visit(SingleVariableDeclaration node) { return visitNode(node); } public boolean visit(VariableDeclarationExpression node) { return visitNode(node); } public boolean visit(VariableDeclarationStatement node) { return visitNode(node); } public boolean visit(VariableDeclarationFragment node) { return visitNode(node); } public boolean visit(WhileStatement node) { return visitNode(node); } /* since 3.0 */ public boolean visit(BlockComment node) { return visitNode(node); } public boolean visit(LineComment node) { return visitNode(node); } public boolean visit(MemberRef node) { return visitNode(node); } public boolean visit(MethodRef node) { return visitNode(node); } public boolean visit(MethodRefParameter node) { return visitNode(node); } public boolean visit(TagElement node) { return visitNode(node); } public boolean visit(TextElement node) { return visitNode(node); } public void endVisit(AnonymousClassDeclaration node) { endVisitNode(node); } public void endVisit(ArrayAccess node) { endVisitNode(node); } public void endVisit(ArrayCreation node) { endVisitNode(node); } public void endVisit(ArrayInitializer node) { endVisitNode(node); } public void endVisit(ArrayType node) { endVisitNode(node); } public void endVisit(AssertStatement node) { endVisitNode(node); } public void endVisit(Assignment node) { endVisitNode(node); } public void endVisit(Block node) { endVisitNode(node); } public void endVisit(BooleanLiteral node) { endVisitNode(node); } public void endVisit(BreakStatement node) { endVisitNode(node); } public void endVisit(CastExpression node) { endVisitNode(node); } public void endVisit(CatchClause node) { endVisitNode(node); } public void endVisit(CharacterLiteral node) { endVisitNode(node); } public void endVisit(ClassInstanceCreation node) { endVisitNode(node); } public void endVisit(CompilationUnit node) { endVisitNode(node); } public void endVisit(ConditionalExpression node) { endVisitNode(node); } public void endVisit(ConstructorInvocation node) { endVisitNode(node); } public void endVisit(ContinueStatement node) { endVisitNode(node); } public void endVisit(DoStatement node) { endVisitNode(node); } public void endVisit(EmptyStatement node) { endVisitNode(node); } public void endVisit(ExpressionStatement node) { endVisitNode(node); } public void endVisit(FieldAccess node) { endVisitNode(node); } public void endVisit(FieldDeclaration node) { endVisitNode(node); } public void endVisit(ForStatement node) { endVisitNode(node); } public void endVisit(IfStatement node) { endVisitNode(node); } public void endVisit(ImportDeclaration node) { endVisitNode(node); } public void endVisit(InfixExpression node) { endVisitNode(node); } public void endVisit(InstanceofExpression node) { endVisitNode(node); } public void endVisit(Initializer node) { endVisitNode(node); } public void endVisit(Javadoc node) { endVisitNode(node); } public void endVisit(LabeledStatement node) { endVisitNode(node); } public void endVisit(MethodDeclaration node) { endVisitNode(node); } public void endVisit(MethodInvocation node) { endVisitNode(node); } public void endVisit(NullLiteral node) { endVisitNode(node); } public void endVisit(NumberLiteral node) { endVisitNode(node); } public void endVisit(PackageDeclaration node) { endVisitNode(node); } public void endVisit(ParenthesizedExpression node) { endVisitNode(node); } public void endVisit(PostfixExpression node) { endVisitNode(node); } public void endVisit(PrefixExpression node) { endVisitNode(node); } public void endVisit(PrimitiveType node) { endVisitNode(node); } public void endVisit(QualifiedName node) { endVisitNode(node); } public void endVisit(ReturnStatement node) { endVisitNode(node); } public void endVisit(SimpleName node) { endVisitNode(node); } public void endVisit(SimpleType node) { endVisitNode(node); } public void endVisit(StringLiteral node) { endVisitNode(node); } public void endVisit(SuperConstructorInvocation node) { endVisitNode(node); } public void endVisit(SuperFieldAccess node) { endVisitNode(node); } public void endVisit(SuperMethodInvocation node) { endVisitNode(node); } public void endVisit(SwitchCase node) { endVisitNode(node); } public void endVisit(SwitchStatement node) { endVisitNode(node); } public void endVisit(SynchronizedStatement node) { endVisitNode(node); } public void endVisit(ThisExpression node) { endVisitNode(node); } public void endVisit(ThrowStatement node) { endVisitNode(node); } public void endVisit(TryStatement node) { endVisitNode(node); } public void endVisit(TypeDeclaration node) { endVisitNode(node); } public void endVisit(TypeDeclarationStatement node) { endVisitNode(node); } public void endVisit(TypeLiteral node) { endVisitNode(node); } public void endVisit(SingleVariableDeclaration node) { endVisitNode(node); } public void endVisit(VariableDeclarationExpression node) { endVisitNode(node); } public void endVisit(VariableDeclarationStatement node) { endVisitNode(node); } public void endVisit(VariableDeclarationFragment node) { endVisitNode(node); } public void endVisit(WhileStatement node) { endVisitNode(node); } /* since 3.0 */ public void endVisit(BlockComment node) { endVisitNode(node); } public void endVisit(LineComment node) { endVisitNode(node); } public void endVisit(MemberRef node) { endVisitNode(node); } public void endVisit(MethodRef node) { endVisitNode(node); } public void endVisit(MethodRefParameter node) { endVisitNode(node); } public void endVisit(TagElement node) { endVisitNode(node); } public void endVisit(TextElement node) { endVisitNode(node); } } /** * Create AST nodes tree for a given compilation unit at a JLS given level * * @deprecated */ private void createAST(ICompilationUnit unit, int astLevel) throws JavaModelException { // Warm up for (int i = 0; i < 2; i++) { ASTParser parser = ASTParser.newParser(astLevel); parser.setSource(unit); parser.setResolveBindings(false); parser.createAST(null); } // Measures int measures = MEASURES_COUNT * 2; int iterations = ITERATIONS_COUNT >> 1; for (int i = 0; i < measures; i++) { ASTNode result = null; runGc(); startMeasuring(); for (int j=0; j<iterations; j++) { ASTParser parser = ASTParser.newParser(astLevel); parser.setSource(unit); parser.setResolveBindings(false); result = parser.createAST(null); } stopMeasuring(); assertEquals("Wrong type for node"+result, result.getNodeType(), ASTNode.COMPILATION_UNIT); CompilationUnit compilationUnit = (CompilationUnit) result; CommentMapperASTVisitor visitor = new CommentMapperASTVisitor(compilationUnit); compilationUnit.accept(visitor); this.nodesCount += visitor.nodes * iterations; } // Commit commitMeasurements(); assertPerformance(); } /** * @deprecated To reduce deprecated warnings */ public void testPerfDomAstCreationJLS2() throws JavaModelException { tagAsSummary("DOM AST tree for one file using JLS2", false); // do NOT put in fingerprint ICompilationUnit unit = getCompilationUnit("org.eclipse.jdt.core", "org.eclipse.jdt.internal.compiler.parser", "Parser.java"); Hashtable options = JavaCore.getOptions(); options.put(JavaCore.COMPILER_PB_NON_NLS_STRING_LITERAL, JavaCore.IGNORE); JavaCore.setOptions(options); createAST(unit, AST.JLS2); } /** * Performance DOM/AST creation on the entire workspace using JLS3. */ public void testPerfDomAstCreationJLS3() throws JavaModelException { tagAsSummary("DOM AST tree for one file using JLS3", false); // do NOT put in fingerprint ICompilationUnit unit = getCompilationUnit("org.eclipse.jdt.core", "org.eclipse.jdt.internal.compiler.parser", "Parser.java"); createAST(unit, JLS3_INTERNAL); } /* * Create AST nodes tree for all compilation units of all projects */ private int runAllProjectsAstCreation(int astLevel) throws JavaModelException { int unitsCount = 0; startMeasuring(); if (DEBUG) System.out.println("Creating AST hierarchy for all units of projects:"); for (int i = 0; i < ALL_PROJECTS.length; i++) { // Get project compilation units if (DEBUG) System.out.print("\t- "+ALL_PROJECTS[i].getElementName()); List units = getProjectCompilationUnits(ALL_PROJECTS[i]); int size = units.size(); if (size == 0) { if (DEBUG) System.out.println(": empty!"); continue; } unitsCount += size; List unitsArrays = splitListInSmallArrays(units, 20); int n = unitsArrays.size(); if (DEBUG) if (n==1) System.out.print(": "+size+" units to proceed ("+n+" step): "); else System.out.print(": "+size+" units to proceed ("+n+" steps): "); while (unitsArrays.size() > 0) { ICompilationUnit[] unitsArray = (ICompilationUnit[]) unitsArrays.remove(0); if (DEBUG) System.out.print('.'); int length = unitsArray.length; CompilationUnit[] compilationUnits = new CompilationUnit[length]; // Create AST tree for (int ptr=0; ptr<length; ptr++) { ICompilationUnit unit = unitsArray[ptr]; unitsArray[ptr] = null; // release memory handle ASTParser parser = ASTParser.newParser(astLevel); parser.setSource(unit); parser.setResolveBindings(false); ASTNode result = parser.createAST(null); assertEquals("Wrong type for node"+result, result.getNodeType(), ASTNode.COMPILATION_UNIT); compilationUnits[ptr] = (CompilationUnit) result; } } if (DEBUG) System.out.println(" done!"); } stopMeasuring(); commitMeasurements(); assertPerformance(); return unitsCount; } /** * @deprecated To reduce deprecated warnings */ public void testWkspDomAstCreationJLS2() throws JavaModelException { tagAsSummary("DOM AST tree for workspace files (JLS2)", false); // do NOT put in fingerprint runAllProjectsAstCreation(AST.JLS2); } /* * Create AST nodes for all compilation unit of a given project */ private void runAstCreation(IJavaProject javaProject) throws JavaModelException { if (DEBUG) System.out.println("Creating AST for project" + javaProject.getElementName()); ASTParser parser = ASTParser.newParser(JLS3_INTERNAL); parser.setResolveBindings(true); parser.setProject(javaProject); Map options= javaProject.getOptions(true); // turn all errors and warnings into ignore. The customizable set of compiler // options only contains additional Eclipse options. The standard JDK compiler // options can't be changed anyway. for (Iterator iter= options.keySet().iterator(); iter.hasNext();) { String key= (String)iter.next(); String value= (String)options.get(key); if ("error".equals(value) || "warning".equals(value)) { //$NON-NLS-1$//$NON-NLS-2$ // System.out.println("Ignoring - " + key); options.put(key, "ignore"); //$NON-NLS-1$ } else if ("enabled".equals(value)) { // System.out.println(" - disabling " + key); options.put(key, "disabled"); } } options.put(JavaCore.COMPILER_TASK_TAGS, ""); parser.setCompilerOptions(options); List units = getProjectCompilationUnits(javaProject); ICompilationUnit[] compilationUnits = new ICompilationUnit[units.size()]; units.toArray(compilationUnits); if (PRINT) { System.out.println(" - options: "+options); System.out.println(" - "+compilationUnits.length+" units will be parsed in "+javaProject.getElementName()+" project"); } // warm up parser.createASTs(compilationUnits, new String[0], new ASTRequestor() { public void acceptAST(ICompilationUnit source, CompilationUnit ast) { IProblem[] problems = ast.getProblems(); int length = problems.length; if (length > 0) { StringBuffer buffer = new StringBuffer(); for (int i=0; i<length; i++) { buffer.append(problems[i].getMessage()); buffer.append('\n'); } assertEquals("Unexpected problems: "+buffer.toString(), 0, length); } } }, null); // Measures int measures = MEASURES_COUNT * 2; for (int i = 0; i < measures; i++) { runGc(); startMeasuring(); parser.createASTs(compilationUnits, new String[0], new ASTRequestor() {/* do nothing*/}, null); stopMeasuring(); } commitMeasurements(); assertPerformance(); } /** * Create AST nodes tree for all compilation units in JUnit project. * * @throws JavaModelException */ public void testDomAstCreationProjectJLS3() throws JavaModelException { tagAsSummary("DOM AST tree for project files (JLS3)", true); // put in fingerprint runAstCreation(getProject("org.eclipse.search")); } }