*******************************************************************************/
package org.eclipse.wst.jsdt.internal.codeassist.impl;
+import java.util.HashMap;
import java.util.Map;
import org.eclipse.wst.jsdt.core.compiler.CharOperation;
public int importCacheCount = 0;
public int onDemandImportCacheCount = 0;
public char[] currentPackageName = null;
+
+ // astInUse is a map from CU to AST and keeps the AST's that is being currently used by resolving mechanism.
+ private static HashMap astInUse = new HashMap();
public Engine(Map settings){
this.options = new AssistOptions(settings);
lookupEnvironment.buildTypeBindings(parsedUnit, accessRestriction);
lookupEnvironment.completeTypeBindings(parsedUnit, true);
}
- public void accept(ICompilationUnit unit, char[][] typeNames, AccessRestriction accessRestriction) {
- CompilationUnitDeclaration parsedUnit = doParse(unit,accessRestriction);
- lookupEnvironment.buildTypeBindings(parsedUnit, typeNames, accessRestriction);
- lookupEnvironment.completeTypeBindings(parsedUnit, typeNames, true);
+ public void accept(ICompilationUnit unit, char[][] typeNames, AccessRestriction accessRestriction) {
+ CompilationUnitDeclaration parsedUnit;
+ boolean astAdded = false;
+ CompilationUnitScope oldScope = null;
+
+ // If the AST is already in memory(namely, it's being used for finding other bindings),
+ // use it instead of parsing again. This reduces performance problem of redundant parsing.
+ if (astInUse.containsKey(unit)) {
+ parsedUnit = (CompilationUnitDeclaration) astInUse.get(unit);
+ } else {
+ parsedUnit = doParse(unit,accessRestriction);
+ astInUse.put(unit, parsedUnit);
+ astAdded = true;
+ }
+ // keeps the scope object of parsedUnit because it will be overwritten in buildTypeBindings()
+ oldScope = parsedUnit.scope;
+
+ try {
+ lookupEnvironment.buildTypeBindings(parsedUnit, typeNames, accessRestriction);
+ lookupEnvironment.completeTypeBindings(parsedUnit, typeNames, true);
+ } finally {
+ // If the AST is added in the current frame, remove it and it'll be GC'ed.
+ if(astAdded) {
+ astInUse.remove(unit);
+ }
+ // restore scope object
+ parsedUnit.scope = oldScope;
+ }
}
/**
this.expressionStack[this.expressionPtr--],
statement,
this.intStack[this.intPtr--],
- this.endStatementPosition);
+ this.scanner.startPosition - 1);
}
protected void consumeStatementExpressionList() {
// StatementExpressionList ::= StatementExpressionList ',' StatementExpression
this.identifierStack[this.identifierPtr],
statement,
this.identifierPositionStack[this.identifierPtr--],
- this.endStatementPosition);
+ this.scanner.startPosition - 1);
this.identifierLengthPtr--;
}
protected void consumeStatementReturn() {