[432978] Support nested at_begin vars
Signed-off-by: Gregory Amerson <gregory.amerson@liferay.com>
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java
index 65f1a23..5392bf6 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2013 IBM Corporation and others.
+ * Copyright (c) 2004, 2014 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
@@ -27,6 +27,7 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.Stack;
@@ -250,6 +251,8 @@
* the ones needed for AT_END variable support.
*/
private StackMap fTagToVariableMap = null;
+ private Map fAtBeginVariableMap = null;
+ private Stack fAtBeginScopeStack = new Stack();
private Stack fUseBeansStack = new Stack();
/** the final translated java document */
@@ -333,9 +336,6 @@
/** The model path as it was persisted */
private IPath fSavedModelPath = null;
- /** the set of variable names that we have declared */
- private Set fDeclSet = new HashSet();
-
/**
* A structure for holding a region collection marker and list of variable
* information. The region can be used later for positioning validation
@@ -344,10 +344,12 @@
static class RegionTags {
ITextRegionCollection region;
CustomTag tag;
+ Collection scopedVarNames = null;
- RegionTags(ITextRegionCollection region, CustomTag tag) {
+ RegionTags(ITextRegionCollection region, CustomTag tag, Collection scopedVarNames) {
this.region = region;
this.tag = tag;
+ this.scopedVarNames = scopedVarNames;
}
}
@@ -644,7 +646,6 @@
fFoundNonTranslatedCode = false;
fCodeTranslated = false;
- fDeclSet.clear();
}
/**
@@ -953,6 +954,8 @@
appendToBuffer(decl, fUserCode, true, customTag);
}
}
+
+ fAtBeginVariableMap.remove( fAtBeginScopeStack.pop() );
}
else {
/*
@@ -975,19 +978,46 @@
CustomTag tag = helper.getCustomTag(tagToAdd, getStructuredDocument(), customTag, problems);
TaglibVariable[] taglibVars = tag.getTagVariables();
fTranslationProblems.addAll(problems);
+ Set scopedVarNames = new HashSet(0);
/*
* Add AT_BEGIN variables
*/
for (int i = 0; i < taglibVars.length; i++) {
if (taglibVars[i].getScope() == VariableInfo.AT_BEGIN) {
- // check to see if we have already declared this variable once, if so then just reassign it instead
- if (fDeclSet.contains(taglibVars[i].getVarName())) {
+ scopedVarNames.add(taglibVars[i].getVarName());
+ boolean declaredInParentScope = false;
+ /*
+ * Check to see if we have already declared this variable
+ * once, if so then just reassign it instead. Declaring twice
+ * in the same scope should cause an error, so we're only
+ * checking parent scopes and the current scope.
+ */
+ RegionTags[] parentTags = (RegionTags[]) fTagToVariableMap.values().toArray(new RegionTags[fTagToVariableMap.size()]);
+ String varName = taglibVars[i].getVarName();
+ for (int j = 0; j < parentTags.length && !declaredInParentScope; j++) {
+ declaredInParentScope |= parentTags[j].scopedVarNames.contains(varName);
+ }
+
+ Set currentAtBeginVars = (Set) fAtBeginVariableMap.get( fAtBeginScopeStack.peek() );
+
+ boolean declaredInCurrentScope = currentAtBeginVars != null && currentAtBeginVars.contains( varName );
+
+ if (declaredInParentScope || declaredInCurrentScope) {
decl = taglibVars[i].getDeclarationString(false, fContext, TaglibVariable.M_REASSIGN);
}
else {
decl = taglibVars[i].getDeclarationString(fContext);
- fDeclSet.add( taglibVars[i].getVarName() );
+
+ if( currentAtBeginVars == null ) {
+ currentAtBeginVars = new HashSet();
+ currentAtBeginVars.add( varName );
+ fAtBeginVariableMap.put( fAtBeginScopeStack.peek(), currentAtBeginVars );
+ }
+ else {
+ currentAtBeginVars.add( varName );
+ }
}
+
appendToBuffer(decl, fUserCode, true, customTag);
}
}
@@ -1015,6 +1045,7 @@
for (int i = 0; i < taglibVars.length; i++) {
if (taglibVars[i].getScope() == VariableInfo.NESTED) {
+ scopedVarNames.add(taglibVars[i].getVarName());
decl = taglibVars[i].getDeclarationString(fContext);
appendToBuffer(decl, fUserCode, true, customTag);
}
@@ -1040,7 +1071,8 @@
/*
* For non-empty tags, remember the variable information
*/
- fTagToVariableMap.push(tagToAdd, new RegionTags(customTag, tag));
+ fTagToVariableMap.push(tagToAdd, new RegionTags(customTag, tag, scopedVarNames));
+ fAtBeginScopeStack.push( tagToAdd );
}
}
@@ -1131,6 +1163,11 @@
if (fTagToVariableMap == null) {
fTagToVariableMap = new StackMap();
}
+ if( fAtBeginVariableMap == null ) {
+ fAtBeginVariableMap = new HashMap();
+ }
+ fAtBeginScopeStack.clear();
+ fAtBeginScopeStack.push( "__root__" ); // need to existing scope for top level customtags
fTranslationProblems.clear();
setCurrentNode(new ZeroStructuredDocumentRegion(fStructuredDocument, 0));
@@ -1192,6 +1229,7 @@
appendToBuffer(text.toString(), fUserCode, false, fStructuredDocument.getLastStructuredDocumentRegion());
}
fTagToVariableMap.clear();
+ fAtBeginVariableMap.clear();
/*
* Now do the same for jsp:useBean tags, whose contents get their own