You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by go...@apache.org on 2013/04/16 05:05:33 UTC
[1/4] Moved MXMLData-related classes into internal package
Updated Branches:
refs/heads/develop 1c7ddc285 -> bec3ba002
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLTagData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLTagData.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLTagData.java
deleted file mode 100644
index 72d77c3..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLTagData.java
+++ /dev/null
@@ -1,1130 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.ListIterator;
-import java.util.Map;
-
-import org.apache.flex.compiler.common.ISourceLocation;
-import org.apache.flex.compiler.common.MutablePrefixMap;
-import org.apache.flex.compiler.common.PrefixMap;
-import org.apache.flex.compiler.common.PrefixedXMLName;
-import org.apache.flex.compiler.common.SourceLocation;
-import org.apache.flex.compiler.common.XMLName;
-import org.apache.flex.compiler.filespecs.IFileSpecification;
-import org.apache.flex.compiler.internal.mxml.MXMLDialect;
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
-import org.apache.flex.compiler.mxml.IMXMLTextData.TextType;
-import org.apache.flex.compiler.parsing.IMXMLToken;
-import org.apache.flex.compiler.parsing.MXMLTokenTypes;
-import org.apache.flex.compiler.problems.ICompilerProblem;
-import org.apache.flex.compiler.problems.MXMLDuplicateAttributeProblem;
-import org.apache.flex.compiler.problems.SyntaxProblem;
-import org.apache.flex.utils.FastStack;
-
-/**
- * Encapsulation of an open tag, a close tag, or an empty tag in MXML.
- */
-public class MXMLTagData extends MXMLUnitData implements IMXMLTagData
-{
- private static final IMXMLTagAttributeData[] NO_ATTRIBUTES = new IMXMLTagAttributeData[0];
-
- /**
- * Constructor.
- */
- public MXMLTagData()
- {
- // Although we don't normally rely on the default ctor to make a completely valid object,
- // in some cases we don't end up calling init, and we end up with a partially construced object.
- // So let's init enough stuff so that the object is well behaved.
- this.attributeMap = Collections.emptyMap();
- this.attributes = NO_ATTRIBUTES;
- }
-
- /**
- * Copy constructor.
- */
- protected MXMLTagData(MXMLTagData other)
- {
- super(other);
- this.nameStart = other.nameStart;
- this.contentEnd = other.contentEnd;
- this.tagName = other.tagName;
- this.nameType = other.nameType;
- this.commentToken = other.commentToken;
- this.stateStart = other.stateStart;
- this.stateName = other.stateName;
- this.attributesStart = other.attributesStart;
- this.emptyTag = other.emptyTag;
- this.explicitCloseToken = other.explicitCloseToken;
- this.attributeMap = other.attributeMap;
- this.attributes = other.attributes;
- this.uri = other.uri;
-
- this.setOffsets(other.getStart(), other.getEnd());
- this.setLine(other.getLine());
- this.setColumn(other.getColumn());
- }
-
- protected String tagName;
-
- /**
- * The URI specified by this tag's prefix.
- */
- protected String uri;
-
- protected String stateName;
-
- /**
- * In-order list of MXML attributes
- */
- protected IMXMLTagAttributeData[] attributes;
-
- /**
- * Map of attribute name to MXML attribute
- */
- protected Map<String, IMXMLTagAttributeData> attributeMap;
-
- /*
- * offset where the tag name starts Note that we also use the for
- * offsetContains(), as it is the first "real" character in the tag
- */
- protected int nameStart;
-
- /*
- * this is the offset of the end of the "stuff inside the punctuation
- */
- protected int contentEnd;
-
- protected int nameType;
-
- /**
- * MXML Comment
- */
- protected IMXMLToken commentToken;
-
- protected int stateStart;
-
- /**
- * Start of the attribute list (after the tag name + whitespace)
- */
- protected int attributesStart;
-
- /**
- * Is this an empty tag (ending with "/>")?
- */
- protected boolean emptyTag;
-
- /**
- * Indicates if we have an explicit close tag
- */
- protected boolean explicitCloseToken;
-
- /*
- * unlike most MXML units, our "content" bounds are not the same as the
- * {@link SourceLocation#getStart()} For tags, we don't count the outer
- * punctuation as "content", although we do count spaces. Example:
- * 0123456789 <foo /> start ==0 contentStart==1 contentEnd== 6 end == 8
- */
- @Override
- public int getContentStart()
- {
- return nameStart;
- }
-
- @Override
- public int getContentEnd()
- {
- return contentEnd;
- }
-
- @SuppressWarnings("fallthrough")
- MutablePrefixMap init(IMXMLData mxmlData, MXMLToken nameToken, ListIterator<MXMLToken> tokenIterator, MXMLDialect dialect, IFileSpecification spec, Collection<ICompilerProblem> problems)
- {
- setSourcePath(mxmlData.getPath());
- MutablePrefixMap map = null;
- emptyTag = false;
- explicitCloseToken = false;
-
- // the start offset will by where '<' is. We strip that text off, but need to remember correct offset first
- int startOffset = nameToken.getStart();
- if (nameToken.getType() == MXMLTokenTypes.TOKEN_OPEN_TAG_START)
- nameToken.truncate(1, 0);
- else if (nameToken.getType() == MXMLTokenTypes.TOKEN_CLOSE_TAG_START)
- nameToken.truncate(2, 0);
- else
- {
- problems.add(new SyntaxProblem(nameToken));
- return map;
- }
-
- // Deal with name if it is of the form name.state
- int nameStart = nameToken.getStart();
- MXMLStateSplitter splitState = new MXMLStateSplitter(nameToken, dialect, problems, spec);
- tagName = splitState.baseName;
- if (splitState.stateName != null)
- {
- stateName = splitState.stateName;
- stateStart = nameToken.getStart() + splitState.stateNameOffset;
- }
-
- nameType = nameToken.getType();
-
- int nameEnd = nameStart + tagName.length();
- int contentEnd = nameEnd;
- setTagOffsets(startOffset, nameEnd, nameStart, contentEnd);
- setColumn(nameToken.getColumn());
- setLine(nameToken.getLine());
- attributesStart = getNameEnd();
- ArrayList<IMXMLTagAttributeData> attrs = new ArrayList<IMXMLTagAttributeData>();
- attributeMap = new LinkedHashMap<String, IMXMLTagAttributeData>(); //preserve order of attrs
- boolean foundTagEnd = false;
- boolean putTokenBack = false; // This is a pre-falcon algorithm that helped recover from tag nesting errors
- // I am bringing it back to life
- while (tokenIterator.hasNext() && !foundTagEnd)
- {
- MXMLToken token = tokenIterator.next();
- MXMLTagAttributeData attribute = null;
- switch (token.getType())
- {
- case MXMLTokenTypes.TOKEN_NAME:
- if (nameType == MXMLTokenTypes.TOKEN_CLOSE_TAG_START)
- {
- problems.add(new SyntaxProblem(token));
- //burn forward until the end tag
- //TODO do we want to mark each token as an error, or just the first?
- while (tokenIterator.hasNext() && !foundTagEnd)
- {
- token = tokenIterator.next();
- switch (token.getType())
- {
- case MXMLTokenTypes.TOKEN_TAG_END:
- case MXMLTokenTypes.TOKEN_EMPTY_TAG_END:
- foundTagEnd = true;
- break;
- }
- }
- break;
- }
- if (token.getText().startsWith("xmlns"))
- {
- attribute = new MXMLNamespaceAttributeData(token, tokenIterator, dialect, spec, problems);
- if (map == null)
- map = new MutablePrefixMap();
- map.add(((IMXMLNamespaceAttributeData)attribute).getNamespacePrefix(), ((IMXMLNamespaceAttributeData)attribute).getNamespace());
- }
- else
- {
- attribute = new MXMLTagAttributeData(token, tokenIterator, dialect, spec, problems);
- }
- attribute.setParent(this);
- // add the attribute to the attributes list even if it is duplicate
- // otherwise code-hinting will not work properly
- if (attributeMap.containsKey(token.getText()))
- {
- MXMLDuplicateAttributeProblem problem = new MXMLDuplicateAttributeProblem(attribute);
- problems.add(problem);
- }
- attrs.add(attribute);
- attributeMap.put(token.getText(), attribute);
-
- // Now advance the offsets to include the newly parsed attributes
- contentEnd = attribute.getAbsoluteEnd();
- setTagOffsets(startOffset, contentEnd, nameStart, contentEnd);
- break;
- case MXMLTokenTypes.TOKEN_TAG_END:
- foundTagEnd = true;
- explicitCloseToken = !token.isImplicit();
- break;
- case MXMLTokenTypes.TOKEN_EMPTY_TAG_END:
- emptyTag = true;
- explicitCloseToken = !token.isImplicit();
- foundTagEnd = true;
- break;
- case MXMLTokenTypes.TOKEN_OPEN_TAG_START:
- case MXMLTokenTypes.TOKEN_CLOSE_TAG_START:
- problems.add(new SyntaxProblem(token));
- foundTagEnd = true; // Don't keep going - bail from malformed tag
- putTokenBack = true;
-
- // if we added this.fEmptyTag = true; then we could repair the damage here,
- // but it's better to let the balancer repair it (in case there is a matching close lurking somewhere)
- break;
- default:
- problems.add(new SyntaxProblem(token));
- break;
- }
- if (foundTagEnd)
- {
- if (token.isImplicit() && token.getStart() == -1)
- {
- explicitCloseToken = false;
- //let's try to end at the start of the next token if one exists
- if (tokenIterator.hasNext())
- {
- MXMLToken next = tokenIterator.next();
- if (next != null)
- {
- // extend the end, but not the content end
- setTagOffsets(getAbsoluteStart() == -1 ? next.getStart() : getAbsoluteStart(), getAbsoluteEnd() == -1 ? next.getStart() : getAbsoluteEnd(), nameStart == -1 ? next.getStart() : nameStart, contentEnd == -1 ? next.getStart() : contentEnd);
- tokenIterator.previous();
- }
- }
- else
- {
- // TODO: if we hit this case do we need to call setTagOffset.
- // and is getNameEnd() correct in any case?
- setOffsets(startOffset, getNameEnd());
- }
- }
- else
- {
- // A Tag's content extends all the way to the end token,
- // so use the token to set content end
- contentEnd = token.getStart();
- if (!putTokenBack)
- {
- // if we are terminating on a "real" close tag, then the "end"
- // of our tag will be the end of the TOKEN_TAG_END
- setTagOffsets(startOffset, token.getEnd(), nameStart, contentEnd);
- }
- else
- {
- // ... conversely, if we are terminating on some other kind of token
- // and are going to push the token back, we definietly don't
- // want to adjust our bounds based on the end of THAT token.
- //
- // So.. use the token start to set the conent end (above) and the end
- setTagOffsets(startOffset, contentEnd, nameStart, contentEnd);
- tokenIterator.previous();
- }
- }
- }
- else if (getAbsoluteEnd() < token.getEnd())
- {
- contentEnd = token.getEnd();
- setTagOffsets(startOffset, contentEnd, nameStart, contentEnd);
- }
- }
- attributes = attrs.toArray(new MXMLTagAttributeData[0]);
- return map;
- }
-
- /**
- * For tags, we "contain" an offset if our content contains the offset. This
- * means that we return false for the outside "<", ">", "</", "/>"
- */
- @Override
- public boolean containsOffset(int offset)
- {
- boolean ret = offset >= nameStart && offset <= contentEnd;
- return ret;
- }
-
- private void setTagOffsets(int start, int end, int contentStart, int contentEnd)
- {
- assert (start <= contentStart) && ((contentStart <= contentEnd) || contentEnd == -1) && ((contentEnd <= end) || (end == -1));
- setOffsets(start, end);
- nameStart = contentStart;
-
- if (contentEnd != -1)
- this.contentEnd = contentEnd;
- }
-
- public void setCommentToken(IMXMLToken commentToken)
- {
- this.commentToken = commentToken;
- }
-
- public IMXMLToken getCommentToken()
- {
- return commentToken;
- }
-
- @Override
- public void setParentUnitDataIndex(int parentIndex)
- {
- //when we fixup tokens, we don't have enough context to determine if we are a root tag. When we're a root tag, we cannot be
- //an emty
- if (emptyTag && !explicitCloseToken)
- {
- if (parentIndex == -1)
- {
- emptyTag = false;
- }
- }
- super.setParentUnitDataIndex(parentIndex);
- }
-
- /**
- * Adjust all associated offsets by the adjustment amount
- *
- * @param offsetAdjustment amount to add to offsets
- */
- @Override
- public void adjustOffsets(int offsetAdjustment)
- {
- super.adjustOffsets(offsetAdjustment);
- nameStart += offsetAdjustment;
- contentEnd += offsetAdjustment;
- if (stateName != null)
- {
- stateStart += offsetAdjustment;
- }
- attributesStart += offsetAdjustment;
- for (int i = 0; i < attributes.length; i++)
- {
- IMXMLTagAttributeData attribute = attributes[i];
- ((MXMLTagAttributeData)attribute).adjustOffsets(offsetAdjustment);
- }
- }
-
- @Override
- public boolean isTag()
- {
- return true;
- }
-
- @Override
- public boolean isEmptyTag()
- {
- return emptyTag;
- }
-
- /**
- * accessor for repair. This lets the balancer mark a tag as empty.
- */
- public void setEmptyTag()
- {
- emptyTag = true;
- }
-
- /**
- * True if this MXMLTagData object has an actual close token, and was not
- * closed as a post-process step of MXML repair
- *
- * @return if we have an explicit close tag
- */
- public boolean hasExplicitCloseTag()
- {
- return explicitCloseToken;
- }
-
- /**
- * Returns true if this tag is the root tag of the containing MXML document
- *
- * @return true if we are the root tag
- */
- public boolean isDocumentRoot()
- {
- if (isOpenTag())
- {
- if (getParentUnitDataIndex() == -1)
- {
- int index = getIndex();
- if (index == 0)
- return true;
- //if we are not zero, scan backwards to see if there is a tag before us
- index--;
- while (index >= 0)
- {
- IMXMLUnitData unit = getParent().getUnit(index);
- if (unit == null || unit.isTag())
- return false;
- index--;
- }
- return true;
- }
- }
- return false;
- }
-
- /**
- * Is this MXML unit an open tag? (i.e. <foo> OR <foo/>, note
- * that the latter is also an empty tag)
- *
- * @return true if the unit is an open tag
- */
- @Override
- public boolean isOpenTag()
- {
- return nameType == MXMLTokenTypes.TOKEN_OPEN_TAG_START;
- }
-
- @Override
- public boolean isOpenAndNotEmptyTag()
- {
- return (isOpenTag() && !isEmptyTag());
- }
-
- @Override
- public boolean isCloseTag()
- {
- return nameType == MXMLTokenTypes.TOKEN_CLOSE_TAG_START;
- }
-
- @Override
- public String getName()
- {
- return tagName;
- }
-
- /**
- * Get the tag name as an {@link PrefixedXMLName}
- *
- * @return the tag name as an {@link PrefixedXMLName}
- */
- public PrefixedXMLName getPrefixedXMLName()
- {
- return new PrefixedXMLName(getName(), getURI());
- }
-
- @Override
- public XMLName getXMLName()
- {
- return new XMLName(getURI(), getShortName());
- }
-
- @Override
- public PrefixMap getPrefixMap()
- {
- return getParent().getPrefixMapForData(this);
- }
-
- @Override
- public PrefixMap getCompositePrefixMap()
- {
- MutablePrefixMap compMap = new MutablePrefixMap();
- IMXMLTagData lookingAt = this;
- while (lookingAt != null)
- {
- PrefixMap depth = getParent().getPrefixMapForData(lookingAt);
- if (depth != null)
- {
- compMap.addAll(depth, true);
- }
- lookingAt = lookingAt.getParentTag();
- }
- return compMap;
- }
-
- @Override
- public String getPrefix()
- {
- String name = getName();
- int i = name.indexOf(':');
- return i != -1 ? name.substring(0, i) : "";
- }
-
- @Override
- public String getShortName()
- {
- String name = getName();
- int i = name.indexOf(':');
- return i != -1 ? name.substring(i + 1) : name;
- }
-
- @Override
- public String getURI()
- {
- if (uri == null)
- {
- //walk up our chain to find the correct uri for our namespace. first one wins
- String prefix = getPrefix();
- IMXMLTagData lookingAt = this;
- while (lookingAt != null)
- {
- PrefixMap depth = getParent().getPrefixMapForData(lookingAt);
- if (depth != null && depth.containsPrefix(prefix))
- {
- uri = depth.getNamespaceForPrefix(prefix);
- break;
- }
- lookingAt = lookingAt.getParentTag();
- }
- }
- return uri;
- }
-
- public void invalidateURI()
- {
- uri = null;
- int length = attributes.length;
- for (int i = 0; i < length; i++)
- {
- ((MXMLTagAttributeData)attributes[i]).invalidateURI();
- }
- }
-
- @Override
- public String getStateName()
- {
- return stateName != null ? stateName : "";
- }
-
- /**
- * Find out if this tag contains the specified attribute.
- *
- * @param attributeName name of the attribute
- * @return true if the attribute is present
- */
- public boolean hasAttribute(String attributeName)
- {
- return attributeMap.containsKey(attributeName);
- }
-
- public boolean hasState()
- {
- return stateName != null;
- }
-
- public int getStateStart()
- {
- return stateStart;
- }
-
- public int getStateEnd()
- {
- return stateName != null ? stateName.length() + stateStart : 0;
- }
-
- @Override
- public String getRawAttributeValue(String attributeName)
- {
- IMXMLTagAttributeData attributeData = attributeMap.get(attributeName);
- if (attributeData != null)
- return attributeData.getRawValue();
- return null;
- }
-
- @Override
- public IMXMLTagAttributeData getTagAttributeData(String attributeName)
- {
- return attributeMap.get(attributeName);
- }
-
- /**
- * Get the start position of the tag name
- *
- * @return the start position of the tag name
- */
- public int getNameStart()
- {
- return nameStart;
- }
-
- /**
- * Get the end position of the tag name
- *
- * @return the end position of the tag name
- */
- public int getNameEnd()
- {
- return nameStart + tagName.length();
- }
-
- /**
- * Get the start position of the state name
- *
- * @return the start position of the tag name
- */
- public int getStateNameStart()
- {
- return stateName != null ? stateStart : -1;
- }
-
- /**
- * Get the end position of the state name
- *
- * @return the end position of the tag name
- */
- public int getStateNameEnd()
- {
- return getStateEnd();
- }
-
- /**
- * Get the start position of the attribute list (after the first whitespace
- * after the tag name).
- *
- * @return the start position of the attribute list
- */
- public int getAttributesStart()
- {
- return attributesStart;
- }
-
- /**
- * Get the end position of the attribute list (before the ">" or "/>" or the
- * start of the next tag).
- *
- * @return the end position of the attribute list
- */
- public int getAttributesEnd()
- {
- return getAbsoluteEnd(); //attr end is just the end of this tag unit
- }
-
- @Override
- public boolean isOffsetInAttributeList(int offset)
- {
- return MXMLData.contains(attributesStart, getAbsoluteEnd(), offset);
- }
-
- public boolean isInsideStateName(int offset)
- {
- if (stateName != null)
- return MXMLData.contains(getStateStart(), getStateEnd(), offset);
- return false;
- }
-
- /**
- * Does the offset fall inside this tag's contents?
- *
- * @param offset test offset
- * @return true iff the offset falls inside this tag's contents
- */
- public boolean isOffsetInsideContents(int offset)
- {
- return MXMLData.contains(getContentStart(), getContentEnd(), // was getContentsEnd (plural)
- offset);
- }
-
- /**
- * Get all of the attribute names in this tag
- *
- * @return all of the attribute names (as a String [])
- */
- public String[] getAttributeNames()
- {
- String[] attributeNames = new String[attributes.length];
- for (int i = 0; i < attributeNames.length; i++)
- {
- attributeNames[i] = attributes[i].getName();
- }
- return attributeNames;
- }
-
- @Override
- public IMXMLTagAttributeData[] getAttributeDatas()
- {
- return attributes;
- }
-
- /**
- * Find the attribute that contains the offset
- *
- * @param offset test offset
- * @return the attribute (or null, if no attribute contains the offset)
- */
- public IMXMLTagAttributeData findAttributeContainingOffset(int offset)
- {
- // Find the last attribute that starts to the left of offset
- IMXMLTagAttributeData lastAttribute = null;
- IMXMLTagAttributeData attribute = null;
- for (int i = 0; i < attributes.length; i++)
- {
- attribute = attributes[i];
- if (attribute.getAbsoluteStart() < offset)
- lastAttribute = attribute;
- else
- break;
- }
- // That last attribute is good if it's unfinished or if it contains the offset in question
- if (lastAttribute != null && (lastAttribute.getAbsoluteEnd() == -1 || lastAttribute.getAbsoluteEnd() >= offset))
- return lastAttribute;
- return null;
- }
-
- /**
- * Collect the text contents of this tag (like <mx:Script> or <mx:Style>)
- *
- * @return the text contents of this tag
- */
- public int[] getTextContentOffsets()
- {
- int startOffset = -1;
- int endOffset = -1;
- if (!isEmptyTag() && isOpenTag())
- {
- IMXMLUnitData[] list = getParent().getUnits();
- int index = getIndex() + 1;
- for (int i = index; i < list.length; i++)
- {
- IMXMLUnitData next = list[i];
- if (next instanceof IMXMLTextData && ((IMXMLTextData)next).getTextType() == TextType.WHITESPACE)
- continue;
- if (next.isText())
- {
- startOffset = startOffset == -1 ? next.getAbsoluteStart() : startOffset;
- endOffset = next.getAbsoluteEnd();
- }
- else
- {
- if (startOffset == -1 && endOffset == -1)
- {
- startOffset = getAbsoluteEnd();
- endOffset = next.getAbsoluteStart();
- }
- break;
- }
- }
- }
- return new int[] {startOffset, endOffset};
- }
-
- @Override
- public String getCompilableText()
- {
- StringBuilder sb = new StringBuilder();
-
- for (IMXMLUnitData unit = getFirstChildUnit(); unit != null; unit = unit.getNextSiblingUnit())
- {
- if (unit.isText())
- sb.append(((IMXMLTextData)unit).getCompilableText());
- }
-
- return sb.toString();
- }
-
- @Override
- public IMXMLTagData findMatchingEndTag()
- {
- return findMatchingEndTag(false);
- }
-
- /**
- * Finds the close tag that matches this tag.
- * <p>
- * Returns null if this tag is a close or empty tag.
- * <p>
- * Returns null if a surrounding tag is unbalanced ONLY if includeImplicit
- * is false; this is determined by backing up to the innermost parent tag
- * with a different tag.
- * <p>
- * {@code <a> <b> <b> <-- find matching for this one will return null
- * </b> </a> * }
- */
- public IMXMLTagData findMatchingEndTag(boolean includeImplicit)
- {
- if (isCloseTag() || isEmptyTag())
- return null;
- // Back up to the first surrounding tag that has a different name, and ensure
- // that *it* is balanced, saving our expected return value along the way.
- IMXMLTagData startTag = this;
- while (true)
- {
- IMXMLTagData parentTag = startTag.getContainingTag(startTag.getAbsoluteStart());
- if (parentTag == null)
- break;
- startTag = parentTag;
- if (!parentTag.getName().equals(this.getName()))
- {
- break;
- }
- }
- // Now walk through the tags starting at startTag. Once we pop ourselves
- // off the tagStack, we've found our candidate result -- but keep going
- // until the stack is null, to ensure that we're balanced out to the
- // surrounding tag.
- IMXMLUnitData[] list = getParent().getUnits();
- FastStack<IMXMLTagData> tagStack = new FastStack<IMXMLTagData>();
- IMXMLTagData result = null;
- for (int i = startTag.getIndex(); i < list.length; i++)
- {
- IMXMLUnitData curUnit = list[i];
- if (curUnit.isTag())
- {
- IMXMLTagData curTag = (IMXMLTagData)curUnit;
- if (curTag.isEmptyTag())
- {
- // do nothing for empty tags.
- }
- else if (curTag.isOpenTag())
- {
- tagStack.push(curTag);
- }
- else if (curTag.isCloseTag())
- {
- if (tagStack.isEmpty())
- {
- // document is unbalanced.
- return null;
- }
- IMXMLTagData pop = tagStack.pop();
-
- //check the short name in case the namespace is not spelled properly
- if (!pop.getName().equals(curTag.getName()) && !pop.getShortName().equals(curTag.getShortName()))
- {
- // document is unbalanced.
- return null;
- }
- if (pop == this)
- {
- // This is our result -- remember it.
- result = curTag;
- }
- if (tagStack.isEmpty())
- {
- if (result.isImplicit() && !includeImplicit)
- return null;
- return result;
- }
- }
- }
- }
- return null;
- }
-
- @Override
- public boolean isImplicit()
- {
- return false;
- }
-
- /**
- * determines if the current tag has an end tag. Will return true if this
- * tag is a close tag or an end tag. If the document is not balanced, we
- * will return false. If the end tag was implicit, we will return false
- *
- * @return true if this tag has an end tag
- */
- public boolean hasEndTag()
- {
- if (isCloseTag() || isEmptyTag())
- return explicitCloseToken;
- IMXMLTagData tagData = findMatchingEndTag();
- return tagData != null && !tagData.isImplicit();
- }
-
- @Override
- public IMXMLUnitData getFirstChildUnit()
- {
- // If this tag is <foo/> then it has no child units.
- if (!isOpenAndNotEmptyTag())
- return null;
-
- IMXMLUnitData next = getNext();
-
- // If this tag is followed immediately by its end tag,
- // as in <foo></foo>, then it has no child units.
- if (next == findMatchingEndTag())
- return null;
-
- // Otherwise, the first child unit is the unit after the tag.
- return next;
- }
-
- @Override
- public IMXMLTagData getFirstChild(boolean includeEmptyTags)
- {
- IMXMLTagData nextTag = null;
- if (isEmptyTag())
- return null;
- if (isOpenTag())
- {
- nextTag = getNextTag();
- }
- else
- {
- // This is a close tag. Start at the corresponding open tag.
- IMXMLTagData openTag = getContainingTag(getAbsoluteStart());
- nextTag = openTag.getNextTag();
- }
- // Skip any text blocks to find the next actual tag. If it's an open tag,
- // that is our first child. Otherwise it's a close tag, return null.
- while (true)
- {
- if (nextTag == null || nextTag.isCloseTag())
- return null;
- if (nextTag.isOpenAndNotEmptyTag() || (nextTag.isEmptyTag() && includeEmptyTags))
- return nextTag;
- nextTag = nextTag.getNextTag();
- }
- }
-
- @Override
- public IMXMLTagData getNextSibling(boolean includeEmptyTags)
- {
- IMXMLTagData nextTag = null;
- // Be sure we're starting at the close tag, then get the next tag.
- if (isCloseTag() || isEmptyTag())
- {
- nextTag = getNextTag();
- }
- else
- {
- IMXMLTagData endTag = findMatchingEndTag();
- if (endTag == null)
- return null;
- nextTag = endTag.getNextTag();
- }
- while (true)
- {
- if (nextTag == null || nextTag.isCloseTag())
- return null;
- if (nextTag.isOpenAndNotEmptyTag() || (nextTag.isEmptyTag() && includeEmptyTags))
- return nextTag;
- nextTag = nextTag.getNextTag();
- }
- }
-
- /**
- * Get the start tags for all children of this tag.
- *
- * @param includeEmptyTags <code>true</code> if empty tags should be
- * included.
- * @return Array of children.
- */
- public IMXMLTagData[] getChildren(boolean includeEmptyTags)
- {
- ArrayList<IMXMLTagData> children = new ArrayList<IMXMLTagData>();
- IMXMLTagData child = getFirstChild(includeEmptyTags);
- while (child != null)
- {
- children.add(child);
- child = child.getNextSibling(includeEmptyTags);
- }
- return children.toArray(new IMXMLTagData[0]);
- }
-
- /**
- * Return the parent tag of this tag. If the document is not balanced before
- * this tag, returns null.
- */
- public IMXMLTagData getParentTag()
- {
- IMXMLUnitData data = getParentUnitData();
- if (data instanceof IMXMLTagData)
- return (IMXMLTagData)data;
- return null;
- }
-
- @Override
- public ISourceLocation getLocationOfChildUnits()
- {
- String sourcePath = getSourcePath();
- int start = getStart();
- int end = getEnd();
- int line = getLine();
- int column = getColumn();
-
- boolean foundFirstChild = false;
-
- for (IMXMLUnitData unit = getFirstChildUnit(); unit != null; unit = unit.getNextSiblingUnit())
- {
- if (!foundFirstChild)
- {
- sourcePath = unit.getSourcePath();
- start = unit.getStart();
- line = unit.getLine();
- column = unit.getColumn();
-
- foundFirstChild = true;
- }
-
- end = unit.getEnd();
- }
-
- return new SourceLocation(sourcePath, start, end, line, column);
- }
-
- /**
- * Verifies that this tag and its attributes have their source location
- * information set.
- * <p>
- * This is used only in asserts.
- */
- @Override
- public boolean verify()
- {
- // Verify the source location.
- super.verify();
-
- // Verify the attributes.
- for (IMXMLTagAttributeData attribute : getAttributeDatas())
- {
- ((MXMLTagAttributeData)attribute).verify();
- }
-
- return true;
- }
-
- /**
- * For debugging only. This format is nice in the Eclipse debugger.
- */
- @Override
- public String toString()
- {
- StringBuilder sb = new StringBuilder();
-
- sb.append('<');
- if (isCloseTag())
- sb.append('/');
- sb.append(getName());
- if (isEmptyTag())
- sb.append('/');
- sb.append('>');
-
- sb.append(' ');
-
- // Display line, column, start, end as "17:5 160-188"
- sb.append(super.toString());
-
- // add content range as "(161-187)"
- sb.append(' ');
- sb.append('(');
- sb.append(nameStart);
- sb.append('-');
- sb.append(contentEnd);
- sb.append(')');
-
- return sb.toString();
- }
-
- /**
- * For debugging only. This format is nice in a text file.
- */
- @Override
- public String toDumpString()
- {
- return buildDumpString(false);
- }
-
- @Override
- public String buildDumpString(boolean skipSrcPath)
- {
- StringBuilder sb = new StringBuilder();
-
- sb.append(super.buildDumpString(skipSrcPath));
-
- sb.append('\t');
-
- sb.append('|');
- sb.append(getName());
- sb.append('|');
-
- return sb.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLTextData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLTextData.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLTextData.java
deleted file mode 100644
index 0d15838..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLTextData.java
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import static org.apache.flex.compiler.constants.IMXMLCoreConstants.*;
-
-import java.util.Collection;
-
-import org.apache.flex.compiler.common.ISourceLocation;
-import org.apache.flex.compiler.internal.mxml.EntityProcessor;
-import org.apache.flex.compiler.internal.mxml.MXMLDialect;
-import org.apache.flex.compiler.internal.parsing.ISourceFragment;
-import org.apache.flex.compiler.internal.parsing.SourceFragment;
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
-import org.apache.flex.compiler.parsing.MXMLTokenTypes;
-import org.apache.flex.compiler.problems.ICompilerProblem;
-
-/**
- * Encapsulation of a block of text in MXML
- */
-public class MXMLTextData extends MXMLUnitData implements IMXMLTextData
-{
- /**
- * Constructor.
- */
- MXMLTextData(MXMLToken textToken)
- {
- text = textToken.getText();
-
- setOffsets(textToken.getStart(), textToken.getEnd());
- setLine(textToken.getLine());
- setColumn(textToken.getColumn());
-
- switch (textToken.getType())
- {
- case MXMLTokenTypes.TOKEN_TEXT:
- {
- type = TextType.TEXT;
- break;
- }
- case MXMLTokenTypes.TOKEN_WHITESPACE:
- {
- type = TextType.WHITESPACE;
- break;
- }
- case MXMLTokenTypes.TOKEN_CDATA:
- {
- type = TextType.CDATA;
- break;
- }
- case MXMLTokenTypes.TOKEN_COMMENT:
- {
- type = TextType.COMMENT;
- break;
- }
- case MXMLTokenTypes.TOKEN_ASDOC_COMMENT:
- {
- type = TextType.ASDOC;
- break;
- }
- default:
- {
- type = TextType.OTHER;
- break;
- }
- }
- }
-
- /**
- * The represented text
- */
- private String text;
-
- private TextType type;
-
- //
- // Object overrides
- //
-
- // For debugging only. This format is nice in the Eclipse debugger.
- @Override
- public String toString()
- {
- StringBuilder sb = new StringBuilder();
-
- // Display TEXT, WHITESPACE, etc.
- sb.append(getTextType());
-
- sb.append(' ');
-
- // Display the text characters.
- sb.append('"');
- sb.append(getEscapedContent());
- sb.append('"');
-
- sb.append(' ');
-
- // Display line, column, start, and end as "17:5 160-188".
- sb.append(super.toString());
-
- return sb.toString();
- }
-
- //
- // MXMLUnitData overrides
- //
-
- @Override
- public boolean isText()
- {
- return true;
- }
-
- // For debugging only.
- @Override
- public String getTypeString()
- {
- StringBuilder sb = new StringBuilder();
-
- sb.append(super.getTypeString());
- sb.append(":");
- sb.append(getTextType());
-
- return sb.toString();
- }
-
- // For debugging only. This format is nice in a text file.
- @Override
- public String toDumpString()
- {
- StringBuilder sb = new StringBuilder();
-
- sb.append(super.toDumpString());
-
- sb.append('\t');
-
- sb.append('|');
- sb.append(getEscapedContent());
- sb.append('|');
-
- return sb.toString();
- }
-
- //
- // IMXMLTextData implementations
- //
-
- @Override
- public String getContent()
- {
- return text;
- }
-
- @Override
- public TextType getTextType()
- {
- return type;
- }
-
- //
- // Other methods
- //
-
- // For debugging only.
- private String getEscapedContent()
- {
- String s = getContent();
-
- s = s.replaceAll("\n", "\\\\n");
- s = s.replaceAll("\r", "\\\\r");
- s = s.replaceAll("\t", "\\\\t");
-
- return s;
- }
-
- @Override
- public String getCompilableText()
- {
- switch (type)
- {
- case TEXT:
- case CDATA:
- case WHITESPACE:
- {
- return getContents();
- }
-
- case ASDOC:
- case COMMENT:
- {
- return "";
- }
- }
-
- assert false;
- return null;
- }
-
- @Override
- public int getCompilableTextStart()
- {
- return getContentsStart();
- }
-
- @Override
- public int getCompilableTextEnd()
- {
- return getContentsEnd();
- }
-
- @Override
- public int getCompilableTextLine()
- {
- return getLine();
- }
-
- @Override
- public int getCompilableTextColumn()
- {
- return (getContentsStart() - getAbsoluteStart()) + getColumn();
- }
-
- /**
- * Return the text contained within this unit, without any opening or
- * closing delimiters
- *
- * @return a normalized string
- */
- public String getContents()
- {
- String tokenString = text;
-
- switch (type)
- {
- case CDATA:
- {
- if (tokenString.endsWith(cDataEnd))
- {
- tokenString = tokenString.substring(cDataStart.length(), tokenString.length() - cDataEnd.length());
- }
- else
- {
- tokenString = tokenString.substring(cDataStart.length());
- }
- return tokenString;
- }
- case ASDOC:
- {
- if (tokenString.endsWith(asDocEnd))
- {
- tokenString = tokenString.substring(asDocStart.length(), tokenString.length() - asDocEnd.length());
- }
- else
- {
- tokenString = tokenString.substring(asDocStart.length());
- }
- return tokenString;
- }
- case COMMENT:
- {
- if (tokenString.endsWith(commentEnd))
- {
- tokenString = tokenString.substring(commentStart.length(), tokenString.length() - commentEnd.length());
- }
- else
- {
- tokenString = tokenString.substring(commentStart.length());
- }
- return tokenString;
- }
- default:
- {
- break;
- }
- }
-
- return text;
- }
-
- /**
- * @return The start offset of actual content
- */
- public int getContentsStart()
- {
- switch (type)
- {
- case CDATA:
- return getAbsoluteStart() + cDataStart.length();
-
- case ASDOC:
- return getAbsoluteStart() + asDocStart.length();
-
- case COMMENT:
- return getAbsoluteStart() + commentStart.length();
-
- case OTHER:
- return getAbsoluteStart();
- }
-
- return getAbsoluteStart();
- }
-
- /**
- * @return The end offset of content
- */
- public int getContentsEnd()
- {
- switch (type)
- {
- case CDATA:
- return text.endsWith(cDataEnd) ? getAbsoluteEnd() - cDataEnd.length() : getAbsoluteEnd();
-
- case ASDOC:
- return text.endsWith(asDocEnd) ? getAbsoluteEnd() - asDocEnd.length() : getAbsoluteEnd();
-
- case COMMENT:
- return text.endsWith(commentEnd) ? getAbsoluteEnd() - commentEnd.length() : getAbsoluteEnd();
-
- case OTHER:
- return getAbsoluteEnd();
- }
-
- return getAbsoluteEnd();
- }
-
- public int getContentsLine()
- {
- return getLine();
- }
-
- public int getContentsColumn()
- {
- switch (type)
- {
- case CDATA:
- return getColumn() + cDataStart.length();
-
- case ASDOC:
- return getColumn() + asDocStart.length();
-
- case COMMENT:
- return getColumn() + commentStart.length();
-
- case OTHER:
- return getColumn();
- }
-
- return getColumn();
- }
-
- @Override
- public ISourceFragment[] getFragments(Collection<ICompilerProblem> problems)
- {
- ISourceLocation location = this;
-
- switch (type)
- {
- case TEXT:
- {
- // TEXT might contain one or more entities,
- // in which case we will return multiple fragments.
- MXMLDialect mxmlDialect = getMXMLDialect();
- return EntityProcessor.parse(text, location, mxmlDialect, problems);
- }
-
- case WHITESPACE:
- {
- // WHITESPACE creates only a single fragment.
- ISourceFragment fragment = new SourceFragment(text, location);
- return new ISourceFragment[] {fragment};
- }
-
- case CDATA:
- {
- // CDATA creates only a single fragment.
- ISourceFragment fragment = new SourceFragment(text, getContents(), getContentsStart(), getContentsLine(), getContentsColumn());
- return new ISourceFragment[] {fragment};
- }
-
- default:
- {
- assert false : "Unexpected type of MXMLTextData";
- }
- }
-
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLTextValue.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLTextValue.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLTextValue.java
deleted file mode 100644
index cdcf255..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLTextValue.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
-import org.apache.flex.compiler.mxml.IMXMLTextData.TextType;
-
-public class MXMLTextValue extends MXMLTagAttributeValue implements
- IMXMLTextValue
-{
- /**
- * Constructor.
- */
- MXMLTextValue(MXMLToken textToken, IMXMLTagAttributeData parent)
- {
- super(parent);
- setStart(textToken.getStart());
- setEnd(textToken.getEnd());
- setColumn(textToken.getColumn());
- setLine(textToken.getLine());
- text = textToken.getText();
- }
-
- private String text;
-
- //
- // Object overrides
- //
-
- /**
- * For debugging only. This format is nice in the Eclipse debugger.
- */
- @Override
- public String toString()
- {
- StringBuilder sb = new StringBuilder();
-
- sb.append("|");
- sb.append(getContent());
- sb.append("| ");
- sb.append(getLine());
- sb.append(" ");
- sb.append(getColumn());
-
- return sb.toString();
- }
-
- //
- // IMXMLTextData implementations
- //
-
- @Override
- public String getContent()
- {
- return text;
- }
-
- @Override
- public TextType getTextType()
- {
- return TextType.TEXT;
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLUnitData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLUnitData.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLUnitData.java
deleted file mode 100644
index 657be38..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLUnitData.java
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import org.apache.flex.compiler.common.SourceLocation;
-import org.apache.flex.compiler.filespecs.FileSpecification;
-import org.apache.flex.compiler.filespecs.IFileSpecification;
-import org.apache.flex.compiler.internal.mxml.MXMLDialect;
-import org.apache.flex.utils.FastStack;
-
-/**
- * Encapsulation of an MXML unit: an open/close/empty tag, a chunk of text
- * (perhaps whitespace, CDATA, or a comment), or a processing instruction.
- * <p>
- * An {@link MXMLData} object stores a linear list of MXML units, but it is
- * possible to walk them in a hierarchical way.
- */
-public abstract class MXMLUnitData extends SourceLocation implements
- IMXMLUnitData
-{
- /**
- * Constructor.
- */
- public MXMLUnitData()
- {
- super();
-
- parent = null;
- index = -1;
- }
-
- /**
- * Copy constructor.
- */
- public MXMLUnitData(MXMLUnitData other)
- {
- this.parent = other.parent;
- this.index = other.index;
- }
-
- /**
- * The {@link MXMLData} object that owns this unit.
- */
- private MXMLData parent;
-
- /**
- * This position of this unit in the linear list of units owned by the
- * {@link MXMLData}.
- */
- protected int index;
-
- /**
- * The position of this unit's parent unit in the linear list of units owned
- * by the {@link MXMLData}.
- */
- private int parentIndex;
-
- @Override
- public int getContentStart()
- {
- return getAbsoluteStart();
- }
-
- @Override
- public int getContentEnd()
- {
- return getAbsoluteEnd();
- }
-
- /**
- * Set this unit's position relative to its parent. Used in parsing.
- *
- * @param parent MXML file containing the unit
- * @param index this unit's position in the list
- */
- public void setLocation(MXMLData parent, int index)
- {
- this.parent = parent;
- this.index = index;
- setSourcePath(parent.getPath());
- }
-
- /**
- * Sets the index of this tags hierarchical parent in its parents array of
- * MXMLUnitData objects
- *
- * @param parentIndex The index of the parent tag.
- */
- public void setParentUnitDataIndex(int parentIndex)
- {
- this.parentIndex = parentIndex;
- }
-
- @Override
- public final IMXMLUnitData getParentUnitData()
- {
- return parent.getUnit(parentIndex);
- }
-
- /**
- * Gets the index of this tags hierarchical parent in its parents array of
- * MXMLUnitData objects
- *
- * @return the index, or -1
- */
- public final int getParentUnitDataIndex()
- {
- return parentIndex;
- }
-
- /**
- * Set this unit's start and end offsets. Used in parsing.
- *
- * @param start start offset
- * @param end end offset
- */
- public void setOffsets(int start, int end)
- {
- setStart(start);
- setEnd(end);
- }
-
- /**
- * Adjust all associated offsets by the adjustment amount
- *
- * @param offsetAdjustment amount to add to offsets
- */
- public void adjustOffsets(int offsetAdjustment)
- {
- setStart(getAbsoluteStart() + offsetAdjustment);
- setEnd(getAbsoluteEnd() + offsetAdjustment);
- }
-
- @Override
- public final IFileSpecification getSource()
- {
- return new FileSpecification(getParent().getPath().toString());
- }
-
- @Override
- public final int getIndex()
- {
- return index;
- }
-
- @Override
- public boolean isText()
- {
- return false;
- }
-
- @Override
- public boolean isTag()
- {
- return false;
- }
-
- @Override
- public boolean isOpenTag()
- {
- return false;
- }
-
- @Override
- public boolean isOpenAndNotEmptyTag()
- {
- return false;
- }
-
- @Override
- public boolean isCloseTag()
- {
- return false;
- }
-
- @Override
- public final IMXMLData getParent()
- {
- return parent;
- }
-
- @Override
- public final IMXMLUnitData getPrevious()
- {
- return parent.getUnit(index - 1);
- }
-
- @Override
- public final IMXMLUnitData getNext()
- {
- return parent.getUnit(index + 1);
- }
-
- @Override
- public final IMXMLUnitData getNextSiblingUnit()
- {
- IMXMLUnitData unit = this;
-
- if (isOpenAndNotEmptyTag())
- unit = ((IMXMLTagData)unit).findMatchingEndTag();
-
- if (unit != null)
- {
- unit = unit.getNext();
-
- if (unit != null && (unit.getParentUnitData() != getParentUnitData()))
- unit = null;
- }
- return unit;
- }
-
- @Override
- public final IMXMLTagData getNextTag()
- {
- IMXMLUnitData nextUnit = getNext();
-
- while (true)
- {
- if (nextUnit == null)
- return null;
-
- if (nextUnit.isTag())
- return (IMXMLTagData)nextUnit;
-
- nextUnit = nextUnit.getNext();
- }
- }
-
- @Override
- public boolean containsOffset(int offset)
- {
- return MXMLData.contains(getAbsoluteStart(), getAbsoluteEnd(), offset);
- }
-
- @Override
- public final IMXMLTagData getContainingTag(int offset)
- {
- FastStack<String> tagNames = new FastStack<String>();
- IMXMLUnitData current = getPrevious();
- IMXMLTagData containingTag = null;
-
- if (containsOffset(offset) && isCloseTag())
- {
- IMXMLTagData tag = (IMXMLTagData)this;
- tagNames.push(tag.getName());
- }
-
- while (current != null && containingTag == null)
- {
- if (current.isTag())
- {
- IMXMLTagData currentTag = (IMXMLTagData)current;
-
- if (currentTag.isCloseTag())
- {
- tagNames.push(currentTag.getName());
- }
- else if (currentTag.isOpenTag() && !currentTag.isEmptyTag())
- {
- String stackName = "";
- while (stackName.compareTo(currentTag.getName()) != 0 && !tagNames.isEmpty())
- {
- stackName = tagNames.pop();
- }
- if (stackName.compareTo(currentTag.getName()) != 0)
- containingTag = currentTag;
- }
- }
-
- current = current.getPrevious();
- }
-
- return containingTag;
- }
-
- @Override
- public MXMLDialect getMXMLDialect()
- {
- return getParent().getMXMLDialect();
- }
-
- protected String getTypeString()
- {
- return getClass().getSimpleName();
- }
-
- /**
- * For debugging only. This format is nice in a text file.
- */
- public String toDumpString()
- {
- return buildDumpString(false);
- }
-
- public String buildDumpString(boolean skipSrcPath)
- {
- StringBuilder sb = new StringBuilder();
-
- sb.append('[');
- sb.append(getIndex());
- sb.append(']');
-
- sb.append('\t');
- if (!skipSrcPath)
- {
- sb.append(getLine() + 1);
- sb.append('\t');
- sb.append(getColumn() + 1);
- sb.append('\t');
- }
- sb.append(getAbsoluteStart());
- sb.append('\t');
- sb.append(getAbsoluteEnd());
- sb.append('\t');
-
- String type = getTypeString();
- sb.append(type);
- int n = 32 - type.length();
- for (int i = 0; i < n; i++)
- sb.append(' ');
- sb.append('\t');
-
- sb.append('^');
- sb.append('[');
- sb.append(parentIndex);
- sb.append(']');
-
- return sb.toString();
- }
-
- /**
- * Verifies that this unit has its source location information set.
- * <p>
- * This is used only in asserts.
- */
- public boolean verify()
- {
- // Verify the source location.
- assert getSourcePath() != null : "MXMLUnitData has null source path: " + toString();
- assert getStart() != UNKNOWN : "MXMLUnitData has unknown start: " + toString();
- assert getEnd() != UNKNOWN : "MXMLUnitData has unknown end: " + toString();
- assert getLine() != UNKNOWN : "MXMLUnitData has unknown line: " + toString();
- assert getColumn() != UNKNOWN : "MXMLUnitData has unknown column: " + toString();
-
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/StateDefinition.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/StateDefinition.java b/compiler/src/org/apache/flex/compiler/mxml/StateDefinition.java
deleted file mode 100644
index c6897b5..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/StateDefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.flex.compiler.scopes.IASScope;
-import org.apache.flex.compiler.tree.mxml.IMXMLStateNode;
-
-/**
- * {@code StateDefinition} represents a state in MXML 2009 or later. States are
- * per-class, so these objects are owned by the {@code ClassDefinitionNodes}
- * that define classes in MXML.
- */
-public class StateDefinition extends StateDefinitionBase implements
- IStateDefinition
-{
- private IMXMLStateNode node;
-
- /**
- * Constructor.
- */
- public StateDefinition(IMXMLStateNode node, IASScope containingScope, String name, int nameStart, int nameEnd)
- {
- super(name, node.getClassDefinitionNode().getDefinition(), containingScope, nameStart, nameEnd);
- this.node = node;
- }
-
- /**
- * A map mapping group names to {@code IStateGroup} objects. This is
- * effectively the set of groups that include this state, but we use a map
- * because we're interested in this set both as a set of group names (the
- * String keys) and a set of group objects (the {@code IStateGroup} values).
- */
- private Map<String, IStateGroupDefinition> groupMap;
-
- @Override
- public IMXMLStateNode getNode()
- {
- return node;
- }
-
- @Override
- public String[] getStateGroups()
- {
- return groupMap != null ? groupMap.keySet().toArray(new String[0]) : new String[0];
- }
-
- @Override
- public IStateGroupDefinition[] resolveStateGroups()
- {
- return groupMap.values().toArray(new IStateGroupDefinition[0]);
- }
-
- @Override
- public boolean isIncludedInStateGroup(String group)
- {
- return groupMap.containsKey(group);
- }
-
- /**
- * Records that this state belongs to a specified group.
- *
- * @param group An {@code IStateGroup} to which this state belongs.
- */
- public void addGroup(IStateGroupDefinition group)
- {
- if (groupMap == null)
- groupMap = new HashMap<String, IStateGroupDefinition>(0);
-
- groupMap.put(group.getBaseName(), group);
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/StateDefinitionBase.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/StateDefinitionBase.java b/compiler/src/org/apache/flex/compiler/mxml/StateDefinitionBase.java
deleted file mode 100644
index 49c675c..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/StateDefinitionBase.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import org.apache.flex.compiler.definitions.IClassDefinition;
-import org.apache.flex.compiler.internal.definitions.DefinitionBase;
-import org.apache.flex.compiler.scopes.IASScope;
-
-/**
- * {@code StateDefinitionBase} is an abstract base class for
- * {@code StateDefinition} and {@code StateGroupDefinition}, which represent
- * states and state groups in MXML 2009 and later.
- */
-public abstract class StateDefinitionBase extends DefinitionBase implements
- IStateDefinitionBase
-{
- /**
- * Constructor.
- */
- public StateDefinitionBase(String name, IClassDefinition containingClass, IASScope containingScope, int nameStart, int nameEnd)
- {
- super(name);
- this.containingClass = containingClass;
- setNameLocation(nameStart, nameEnd);
- setContainingScope(containingScope);
- }
-
- private final IClassDefinition containingClass;
-
- @Override
- public boolean isImplicit()
- {
- return true; //this node will always be implicit, even though it will have offsets
- }
-
- @Override
- public int compareTo(IStateDefinitionBase other)
- {
- return getNameStart() - other.getNameStart();
- }
-
- /**
- * For debugging only.
- */
- @Override
- public String toString()
- {
- return getBaseName();
- }
-
- @Override
- public IClassDefinition getContainingClass()
- {
- return containingClass;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/StateGroupDefinition.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/StateGroupDefinition.java b/compiler/src/org/apache/flex/compiler/mxml/StateGroupDefinition.java
deleted file mode 100644
index 19fc74f..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/StateGroupDefinition.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.flex.compiler.definitions.IClassDefinition;
-
-/**
- * {@code StateGroupDefinition} represents a state group in an MXML class.
- */
-public class StateGroupDefinition extends StateDefinitionBase implements
- IStateGroupDefinition
-{
- /**
- * Constructor.
- */
- public StateGroupDefinition(String name, IClassDefinition containingClass)
- {
- super(name, containingClass, containingClass.getContainedScope(), -1, -1);
-
- }
-
- /**
- * A map mapping state names to {@code IStateDefinition} objects. This is
- * effectively the set of states included in this group, but we use a map
- * because we're interested in this set both as a set of state names (the
- * String keys) and a set of state objects (the {@code IStateDefinition}
- * values).
- */
- private Map<String, IStateDefinition> stateMap;
-
- @Override
- public String[] getIncludedStates()
- {
- return stateMap.keySet().toArray(new String[0]);
- }
-
- @Override
- public IStateDefinition[] resolveIncludedStates()
- {
- return stateMap.values().toArray(new IStateDefinition[0]);
- }
-
- @Override
- public boolean isStateIncluded(String state)
- {
- return stateMap.containsKey(state);
- }
-
- /**
- * Records that this group includes a specified state.
- *
- * @param state An {@code IStateDefinition} that this group includes.
- */
- public void addState(IStateDefinition state)
- {
- if (stateMap == null)
- stateMap = new HashMap<String, IStateDefinition>(0);
-
- stateMap.put(state.getBaseName(), state);
- }
-
-}
[3/4] Moved MXMLData-related classes into internal package
Posted by go...@apache.org.
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagAttributeValue.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagAttributeValue.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagAttributeValue.java
new file mode 100644
index 0000000..994cf14
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagAttributeValue.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import org.apache.flex.compiler.common.SourceLocation;
+import org.apache.flex.compiler.mxml.IMXMLTagAttributeData;
+import org.apache.flex.compiler.mxml.IMXMLTagAttributeValue;
+
+public abstract class MXMLTagAttributeValue extends SourceLocation implements
+ IMXMLTagAttributeValue
+{
+ /**
+ * Constructor.
+ */
+ public MXMLTagAttributeValue(IMXMLTagAttributeData parent)
+ {
+ this.parent = parent;
+
+ if (parent != null)
+ setSourcePath(parent.getSourcePath());
+ }
+
+ /**
+ * The MXML attribute that contains this unit
+ */
+ private IMXMLTagAttributeData parent;
+
+ //
+ // Other methods
+ //
+
+ public IMXMLTagAttributeData getContainingAttribute()
+ {
+ return parent;
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagBlobData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagBlobData.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagBlobData.java
new file mode 100644
index 0000000..78b167d
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagBlobData.java
@@ -0,0 +1,66 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
+import org.apache.flex.compiler.mxml.IMXMLTagBlobData;
+
+/**
+ * An MXML blob is a large chunk of MXML data that was passed over during
+ * tokenization. A blob, for example could be the contents of an fx:Private tag.
+ */
+public class MXMLTagBlobData extends MXMLUnitData implements IMXMLTagBlobData
+{
+ /**
+ * Constructor.
+ *
+ * @param token
+ */
+ MXMLTagBlobData(MXMLToken token)
+ {
+ String text = token.getText();
+ int length = text.length();
+ int pos = 1;
+ while (pos < length)
+ {
+ if (Character.isWhitespace(text.charAt(pos)))
+ break;
+ pos++;
+ }
+ name = text.substring(1, pos - 1);
+
+ setStart(token.getStart());
+ setEnd(token.getEnd());
+ setLine(token.getLine());
+ setColumn(token.getColumn());
+ }
+
+ private String name;
+
+ //
+ // IMXMLTagBlobData implementations
+ //
+
+ @Override
+ public String getName()
+ {
+ return name;
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagData.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagData.java
new file mode 100644
index 0000000..b72da1d
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagData.java
@@ -0,0 +1,1135 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.apache.flex.compiler.common.ISourceLocation;
+import org.apache.flex.compiler.common.MutablePrefixMap;
+import org.apache.flex.compiler.common.PrefixMap;
+import org.apache.flex.compiler.common.PrefixedXMLName;
+import org.apache.flex.compiler.common.SourceLocation;
+import org.apache.flex.compiler.common.XMLName;
+import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
+import org.apache.flex.compiler.mxml.IMXMLData;
+import org.apache.flex.compiler.mxml.IMXMLNamespaceAttributeData;
+import org.apache.flex.compiler.mxml.IMXMLTagAttributeData;
+import org.apache.flex.compiler.mxml.IMXMLTagData;
+import org.apache.flex.compiler.mxml.IMXMLTextData;
+import org.apache.flex.compiler.mxml.IMXMLUnitData;
+import org.apache.flex.compiler.mxml.IMXMLTextData.TextType;
+import org.apache.flex.compiler.parsing.IMXMLToken;
+import org.apache.flex.compiler.parsing.MXMLTokenTypes;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.problems.MXMLDuplicateAttributeProblem;
+import org.apache.flex.compiler.problems.SyntaxProblem;
+import org.apache.flex.utils.FastStack;
+
+/**
+ * Encapsulation of an open tag, a close tag, or an empty tag in MXML.
+ */
+public class MXMLTagData extends MXMLUnitData implements IMXMLTagData
+{
+ private static final IMXMLTagAttributeData[] NO_ATTRIBUTES = new IMXMLTagAttributeData[0];
+
+ /**
+ * Constructor.
+ */
+ public MXMLTagData()
+ {
+ // Although we don't normally rely on the default ctor to make a completely valid object,
+ // in some cases we don't end up calling init, and we end up with a partially construced object.
+ // So let's init enough stuff so that the object is well behaved.
+ this.attributeMap = Collections.emptyMap();
+ this.attributes = NO_ATTRIBUTES;
+ }
+
+ /**
+ * Copy constructor.
+ */
+ protected MXMLTagData(MXMLTagData other)
+ {
+ super(other);
+ this.nameStart = other.nameStart;
+ this.contentEnd = other.contentEnd;
+ this.tagName = other.tagName;
+ this.nameType = other.nameType;
+ this.commentToken = other.commentToken;
+ this.stateStart = other.stateStart;
+ this.stateName = other.stateName;
+ this.attributesStart = other.attributesStart;
+ this.emptyTag = other.emptyTag;
+ this.explicitCloseToken = other.explicitCloseToken;
+ this.attributeMap = other.attributeMap;
+ this.attributes = other.attributes;
+ this.uri = other.uri;
+
+ this.setOffsets(other.getStart(), other.getEnd());
+ this.setLine(other.getLine());
+ this.setColumn(other.getColumn());
+ }
+
+ protected String tagName;
+
+ /**
+ * The URI specified by this tag's prefix.
+ */
+ protected String uri;
+
+ protected String stateName;
+
+ /**
+ * In-order list of MXML attributes
+ */
+ protected IMXMLTagAttributeData[] attributes;
+
+ /**
+ * Map of attribute name to MXML attribute
+ */
+ protected Map<String, IMXMLTagAttributeData> attributeMap;
+
+ /*
+ * offset where the tag name starts Note that we also use the for
+ * offsetContains(), as it is the first "real" character in the tag
+ */
+ protected int nameStart;
+
+ /*
+ * this is the offset of the end of the "stuff inside the punctuation
+ */
+ protected int contentEnd;
+
+ protected int nameType;
+
+ /**
+ * MXML Comment
+ */
+ protected IMXMLToken commentToken;
+
+ protected int stateStart;
+
+ /**
+ * Start of the attribute list (after the tag name + whitespace)
+ */
+ protected int attributesStart;
+
+ /**
+ * Is this an empty tag (ending with "/>")?
+ */
+ protected boolean emptyTag;
+
+ /**
+ * Indicates if we have an explicit close tag
+ */
+ protected boolean explicitCloseToken;
+
+ /*
+ * unlike most MXML units, our "content" bounds are not the same as the
+ * {@link SourceLocation#getStart()} For tags, we don't count the outer
+ * punctuation as "content", although we do count spaces. Example:
+ * 0123456789 <foo /> start ==0 contentStart==1 contentEnd== 6 end == 8
+ */
+ @Override
+ public int getContentStart()
+ {
+ return nameStart;
+ }
+
+ @Override
+ public int getContentEnd()
+ {
+ return contentEnd;
+ }
+
+ @SuppressWarnings("fallthrough")
+ MutablePrefixMap init(IMXMLData mxmlData, MXMLToken nameToken, ListIterator<MXMLToken> tokenIterator, MXMLDialect dialect, IFileSpecification spec, Collection<ICompilerProblem> problems)
+ {
+ setSourcePath(mxmlData.getPath());
+ MutablePrefixMap map = null;
+ emptyTag = false;
+ explicitCloseToken = false;
+
+ // the start offset will by where '<' is. We strip that text off, but need to remember correct offset first
+ int startOffset = nameToken.getStart();
+ if (nameToken.getType() == MXMLTokenTypes.TOKEN_OPEN_TAG_START)
+ nameToken.truncate(1, 0);
+ else if (nameToken.getType() == MXMLTokenTypes.TOKEN_CLOSE_TAG_START)
+ nameToken.truncate(2, 0);
+ else
+ {
+ problems.add(new SyntaxProblem(nameToken));
+ return map;
+ }
+
+ // Deal with name if it is of the form name.state
+ int nameStart = nameToken.getStart();
+ MXMLStateSplitter splitState = new MXMLStateSplitter(nameToken, dialect, problems, spec);
+ tagName = splitState.baseName;
+ if (splitState.stateName != null)
+ {
+ stateName = splitState.stateName;
+ stateStart = nameToken.getStart() + splitState.stateNameOffset;
+ }
+
+ nameType = nameToken.getType();
+
+ int nameEnd = nameStart + tagName.length();
+ int contentEnd = nameEnd;
+ setTagOffsets(startOffset, nameEnd, nameStart, contentEnd);
+ setColumn(nameToken.getColumn());
+ setLine(nameToken.getLine());
+ attributesStart = getNameEnd();
+ ArrayList<IMXMLTagAttributeData> attrs = new ArrayList<IMXMLTagAttributeData>();
+ attributeMap = new LinkedHashMap<String, IMXMLTagAttributeData>(); //preserve order of attrs
+ boolean foundTagEnd = false;
+ boolean putTokenBack = false; // This is a pre-falcon algorithm that helped recover from tag nesting errors
+ // I am bringing it back to life
+ while (tokenIterator.hasNext() && !foundTagEnd)
+ {
+ MXMLToken token = tokenIterator.next();
+ MXMLTagAttributeData attribute = null;
+ switch (token.getType())
+ {
+ case MXMLTokenTypes.TOKEN_NAME:
+ if (nameType == MXMLTokenTypes.TOKEN_CLOSE_TAG_START)
+ {
+ problems.add(new SyntaxProblem(token));
+ //burn forward until the end tag
+ //TODO do we want to mark each token as an error, or just the first?
+ while (tokenIterator.hasNext() && !foundTagEnd)
+ {
+ token = tokenIterator.next();
+ switch (token.getType())
+ {
+ case MXMLTokenTypes.TOKEN_TAG_END:
+ case MXMLTokenTypes.TOKEN_EMPTY_TAG_END:
+ foundTagEnd = true;
+ break;
+ }
+ }
+ break;
+ }
+ if (token.getText().startsWith("xmlns"))
+ {
+ attribute = new MXMLNamespaceAttributeData(token, tokenIterator, dialect, spec, problems);
+ if (map == null)
+ map = new MutablePrefixMap();
+ map.add(((IMXMLNamespaceAttributeData)attribute).getNamespacePrefix(), ((IMXMLNamespaceAttributeData)attribute).getNamespace());
+ }
+ else
+ {
+ attribute = new MXMLTagAttributeData(token, tokenIterator, dialect, spec, problems);
+ }
+ attribute.setParent(this);
+ // add the attribute to the attributes list even if it is duplicate
+ // otherwise code-hinting will not work properly
+ if (attributeMap.containsKey(token.getText()))
+ {
+ MXMLDuplicateAttributeProblem problem = new MXMLDuplicateAttributeProblem(attribute);
+ problems.add(problem);
+ }
+ attrs.add(attribute);
+ attributeMap.put(token.getText(), attribute);
+
+ // Now advance the offsets to include the newly parsed attributes
+ contentEnd = attribute.getAbsoluteEnd();
+ setTagOffsets(startOffset, contentEnd, nameStart, contentEnd);
+ break;
+ case MXMLTokenTypes.TOKEN_TAG_END:
+ foundTagEnd = true;
+ explicitCloseToken = !token.isImplicit();
+ break;
+ case MXMLTokenTypes.TOKEN_EMPTY_TAG_END:
+ emptyTag = true;
+ explicitCloseToken = !token.isImplicit();
+ foundTagEnd = true;
+ break;
+ case MXMLTokenTypes.TOKEN_OPEN_TAG_START:
+ case MXMLTokenTypes.TOKEN_CLOSE_TAG_START:
+ problems.add(new SyntaxProblem(token));
+ foundTagEnd = true; // Don't keep going - bail from malformed tag
+ putTokenBack = true;
+
+ // if we added this.fEmptyTag = true; then we could repair the damage here,
+ // but it's better to let the balancer repair it (in case there is a matching close lurking somewhere)
+ break;
+ default:
+ problems.add(new SyntaxProblem(token));
+ break;
+ }
+ if (foundTagEnd)
+ {
+ if (token.isImplicit() && token.getStart() == -1)
+ {
+ explicitCloseToken = false;
+ //let's try to end at the start of the next token if one exists
+ if (tokenIterator.hasNext())
+ {
+ MXMLToken next = tokenIterator.next();
+ if (next != null)
+ {
+ // extend the end, but not the content end
+ setTagOffsets(getAbsoluteStart() == -1 ? next.getStart() : getAbsoluteStart(), getAbsoluteEnd() == -1 ? next.getStart() : getAbsoluteEnd(), nameStart == -1 ? next.getStart() : nameStart, contentEnd == -1 ? next.getStart() : contentEnd);
+ tokenIterator.previous();
+ }
+ }
+ else
+ {
+ // TODO: if we hit this case do we need to call setTagOffset.
+ // and is getNameEnd() correct in any case?
+ setOffsets(startOffset, getNameEnd());
+ }
+ }
+ else
+ {
+ // A Tag's content extends all the way to the end token,
+ // so use the token to set content end
+ contentEnd = token.getStart();
+ if (!putTokenBack)
+ {
+ // if we are terminating on a "real" close tag, then the "end"
+ // of our tag will be the end of the TOKEN_TAG_END
+ setTagOffsets(startOffset, token.getEnd(), nameStart, contentEnd);
+ }
+ else
+ {
+ // ... conversely, if we are terminating on some other kind of token
+ // and are going to push the token back, we definietly don't
+ // want to adjust our bounds based on the end of THAT token.
+ //
+ // So.. use the token start to set the conent end (above) and the end
+ setTagOffsets(startOffset, contentEnd, nameStart, contentEnd);
+ tokenIterator.previous();
+ }
+ }
+ }
+ else if (getAbsoluteEnd() < token.getEnd())
+ {
+ contentEnd = token.getEnd();
+ setTagOffsets(startOffset, contentEnd, nameStart, contentEnd);
+ }
+ }
+ attributes = attrs.toArray(new MXMLTagAttributeData[0]);
+ return map;
+ }
+
+ /**
+ * For tags, we "contain" an offset if our content contains the offset. This
+ * means that we return false for the outside "<", ">", "</", "/>"
+ */
+ @Override
+ public boolean containsOffset(int offset)
+ {
+ boolean ret = offset >= nameStart && offset <= contentEnd;
+ return ret;
+ }
+
+ private void setTagOffsets(int start, int end, int contentStart, int contentEnd)
+ {
+ assert (start <= contentStart) && ((contentStart <= contentEnd) || contentEnd == -1) && ((contentEnd <= end) || (end == -1));
+ setOffsets(start, end);
+ nameStart = contentStart;
+
+ if (contentEnd != -1)
+ this.contentEnd = contentEnd;
+ }
+
+ public void setCommentToken(IMXMLToken commentToken)
+ {
+ this.commentToken = commentToken;
+ }
+
+ public IMXMLToken getCommentToken()
+ {
+ return commentToken;
+ }
+
+ @Override
+ public void setParentUnitDataIndex(int parentIndex)
+ {
+ //when we fixup tokens, we don't have enough context to determine if we are a root tag. When we're a root tag, we cannot be
+ //an emty
+ if (emptyTag && !explicitCloseToken)
+ {
+ if (parentIndex == -1)
+ {
+ emptyTag = false;
+ }
+ }
+ super.setParentUnitDataIndex(parentIndex);
+ }
+
+ /**
+ * Adjust all associated offsets by the adjustment amount
+ *
+ * @param offsetAdjustment amount to add to offsets
+ */
+ @Override
+ public void adjustOffsets(int offsetAdjustment)
+ {
+ super.adjustOffsets(offsetAdjustment);
+ nameStart += offsetAdjustment;
+ contentEnd += offsetAdjustment;
+ if (stateName != null)
+ {
+ stateStart += offsetAdjustment;
+ }
+ attributesStart += offsetAdjustment;
+ for (int i = 0; i < attributes.length; i++)
+ {
+ IMXMLTagAttributeData attribute = attributes[i];
+ ((MXMLTagAttributeData)attribute).adjustOffsets(offsetAdjustment);
+ }
+ }
+
+ @Override
+ public boolean isTag()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isEmptyTag()
+ {
+ return emptyTag;
+ }
+
+ /**
+ * accessor for repair. This lets the balancer mark a tag as empty.
+ */
+ public void setEmptyTag()
+ {
+ emptyTag = true;
+ }
+
+ /**
+ * True if this MXMLTagData object has an actual close token, and was not
+ * closed as a post-process step of MXML repair
+ *
+ * @return if we have an explicit close tag
+ */
+ public boolean hasExplicitCloseTag()
+ {
+ return explicitCloseToken;
+ }
+
+ /**
+ * Returns true if this tag is the root tag of the containing MXML document
+ *
+ * @return true if we are the root tag
+ */
+ public boolean isDocumentRoot()
+ {
+ if (isOpenTag())
+ {
+ if (getParentUnitDataIndex() == -1)
+ {
+ int index = getIndex();
+ if (index == 0)
+ return true;
+ //if we are not zero, scan backwards to see if there is a tag before us
+ index--;
+ while (index >= 0)
+ {
+ IMXMLUnitData unit = getParent().getUnit(index);
+ if (unit == null || unit.isTag())
+ return false;
+ index--;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Is this MXML unit an open tag? (i.e. <foo> OR <foo/>, note
+ * that the latter is also an empty tag)
+ *
+ * @return true if the unit is an open tag
+ */
+ @Override
+ public boolean isOpenTag()
+ {
+ return nameType == MXMLTokenTypes.TOKEN_OPEN_TAG_START;
+ }
+
+ @Override
+ public boolean isOpenAndNotEmptyTag()
+ {
+ return (isOpenTag() && !isEmptyTag());
+ }
+
+ @Override
+ public boolean isCloseTag()
+ {
+ return nameType == MXMLTokenTypes.TOKEN_CLOSE_TAG_START;
+ }
+
+ @Override
+ public String getName()
+ {
+ return tagName;
+ }
+
+ /**
+ * Get the tag name as an {@link PrefixedXMLName}
+ *
+ * @return the tag name as an {@link PrefixedXMLName}
+ */
+ public PrefixedXMLName getPrefixedXMLName()
+ {
+ return new PrefixedXMLName(getName(), getURI());
+ }
+
+ @Override
+ public XMLName getXMLName()
+ {
+ return new XMLName(getURI(), getShortName());
+ }
+
+ @Override
+ public PrefixMap getPrefixMap()
+ {
+ return getParent().getPrefixMapForData(this);
+ }
+
+ @Override
+ public PrefixMap getCompositePrefixMap()
+ {
+ MutablePrefixMap compMap = new MutablePrefixMap();
+ IMXMLTagData lookingAt = this;
+ while (lookingAt != null)
+ {
+ PrefixMap depth = getParent().getPrefixMapForData(lookingAt);
+ if (depth != null)
+ {
+ compMap.addAll(depth, true);
+ }
+ lookingAt = lookingAt.getParentTag();
+ }
+ return compMap;
+ }
+
+ @Override
+ public String getPrefix()
+ {
+ String name = getName();
+ int i = name.indexOf(':');
+ return i != -1 ? name.substring(0, i) : "";
+ }
+
+ @Override
+ public String getShortName()
+ {
+ String name = getName();
+ int i = name.indexOf(':');
+ return i != -1 ? name.substring(i + 1) : name;
+ }
+
+ @Override
+ public String getURI()
+ {
+ if (uri == null)
+ {
+ //walk up our chain to find the correct uri for our namespace. first one wins
+ String prefix = getPrefix();
+ IMXMLTagData lookingAt = this;
+ while (lookingAt != null)
+ {
+ PrefixMap depth = getParent().getPrefixMapForData(lookingAt);
+ if (depth != null && depth.containsPrefix(prefix))
+ {
+ uri = depth.getNamespaceForPrefix(prefix);
+ break;
+ }
+ lookingAt = lookingAt.getParentTag();
+ }
+ }
+ return uri;
+ }
+
+ public void invalidateURI()
+ {
+ uri = null;
+ int length = attributes.length;
+ for (int i = 0; i < length; i++)
+ {
+ ((MXMLTagAttributeData)attributes[i]).invalidateURI();
+ }
+ }
+
+ @Override
+ public String getStateName()
+ {
+ return stateName != null ? stateName : "";
+ }
+
+ /**
+ * Find out if this tag contains the specified attribute.
+ *
+ * @param attributeName name of the attribute
+ * @return true if the attribute is present
+ */
+ public boolean hasAttribute(String attributeName)
+ {
+ return attributeMap.containsKey(attributeName);
+ }
+
+ public boolean hasState()
+ {
+ return stateName != null;
+ }
+
+ public int getStateStart()
+ {
+ return stateStart;
+ }
+
+ public int getStateEnd()
+ {
+ return stateName != null ? stateName.length() + stateStart : 0;
+ }
+
+ @Override
+ public String getRawAttributeValue(String attributeName)
+ {
+ IMXMLTagAttributeData attributeData = attributeMap.get(attributeName);
+ if (attributeData != null)
+ return attributeData.getRawValue();
+ return null;
+ }
+
+ @Override
+ public IMXMLTagAttributeData getTagAttributeData(String attributeName)
+ {
+ return attributeMap.get(attributeName);
+ }
+
+ /**
+ * Get the start position of the tag name
+ *
+ * @return the start position of the tag name
+ */
+ public int getNameStart()
+ {
+ return nameStart;
+ }
+
+ /**
+ * Get the end position of the tag name
+ *
+ * @return the end position of the tag name
+ */
+ public int getNameEnd()
+ {
+ return nameStart + tagName.length();
+ }
+
+ /**
+ * Get the start position of the state name
+ *
+ * @return the start position of the tag name
+ */
+ public int getStateNameStart()
+ {
+ return stateName != null ? stateStart : -1;
+ }
+
+ /**
+ * Get the end position of the state name
+ *
+ * @return the end position of the tag name
+ */
+ public int getStateNameEnd()
+ {
+ return getStateEnd();
+ }
+
+ /**
+ * Get the start position of the attribute list (after the first whitespace
+ * after the tag name).
+ *
+ * @return the start position of the attribute list
+ */
+ public int getAttributesStart()
+ {
+ return attributesStart;
+ }
+
+ /**
+ * Get the end position of the attribute list (before the ">" or "/>" or the
+ * start of the next tag).
+ *
+ * @return the end position of the attribute list
+ */
+ public int getAttributesEnd()
+ {
+ return getAbsoluteEnd(); //attr end is just the end of this tag unit
+ }
+
+ @Override
+ public boolean isOffsetInAttributeList(int offset)
+ {
+ return MXMLData.contains(attributesStart, getAbsoluteEnd(), offset);
+ }
+
+ public boolean isInsideStateName(int offset)
+ {
+ if (stateName != null)
+ return MXMLData.contains(getStateStart(), getStateEnd(), offset);
+ return false;
+ }
+
+ /**
+ * Does the offset fall inside this tag's contents?
+ *
+ * @param offset test offset
+ * @return true iff the offset falls inside this tag's contents
+ */
+ public boolean isOffsetInsideContents(int offset)
+ {
+ return MXMLData.contains(getContentStart(), getContentEnd(), // was getContentsEnd (plural)
+ offset);
+ }
+
+ /**
+ * Get all of the attribute names in this tag
+ *
+ * @return all of the attribute names (as a String [])
+ */
+ public String[] getAttributeNames()
+ {
+ String[] attributeNames = new String[attributes.length];
+ for (int i = 0; i < attributeNames.length; i++)
+ {
+ attributeNames[i] = attributes[i].getName();
+ }
+ return attributeNames;
+ }
+
+ @Override
+ public IMXMLTagAttributeData[] getAttributeDatas()
+ {
+ return attributes;
+ }
+
+ /**
+ * Find the attribute that contains the offset
+ *
+ * @param offset test offset
+ * @return the attribute (or null, if no attribute contains the offset)
+ */
+ public IMXMLTagAttributeData findAttributeContainingOffset(int offset)
+ {
+ // Find the last attribute that starts to the left of offset
+ IMXMLTagAttributeData lastAttribute = null;
+ IMXMLTagAttributeData attribute = null;
+ for (int i = 0; i < attributes.length; i++)
+ {
+ attribute = attributes[i];
+ if (attribute.getAbsoluteStart() < offset)
+ lastAttribute = attribute;
+ else
+ break;
+ }
+ // That last attribute is good if it's unfinished or if it contains the offset in question
+ if (lastAttribute != null && (lastAttribute.getAbsoluteEnd() == -1 || lastAttribute.getAbsoluteEnd() >= offset))
+ return lastAttribute;
+ return null;
+ }
+
+ /**
+ * Collect the text contents of this tag (like <mx:Script> or <mx:Style>)
+ *
+ * @return the text contents of this tag
+ */
+ public int[] getTextContentOffsets()
+ {
+ int startOffset = -1;
+ int endOffset = -1;
+ if (!isEmptyTag() && isOpenTag())
+ {
+ IMXMLUnitData[] list = getParent().getUnits();
+ int index = getIndex() + 1;
+ for (int i = index; i < list.length; i++)
+ {
+ IMXMLUnitData next = list[i];
+ if (next instanceof IMXMLTextData && ((IMXMLTextData)next).getTextType() == TextType.WHITESPACE)
+ continue;
+ if (next.isText())
+ {
+ startOffset = startOffset == -1 ? next.getAbsoluteStart() : startOffset;
+ endOffset = next.getAbsoluteEnd();
+ }
+ else
+ {
+ if (startOffset == -1 && endOffset == -1)
+ {
+ startOffset = getAbsoluteEnd();
+ endOffset = next.getAbsoluteStart();
+ }
+ break;
+ }
+ }
+ }
+ return new int[] {startOffset, endOffset};
+ }
+
+ @Override
+ public String getCompilableText()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ for (IMXMLUnitData unit = getFirstChildUnit(); unit != null; unit = unit.getNextSiblingUnit())
+ {
+ if (unit.isText())
+ sb.append(((IMXMLTextData)unit).getCompilableText());
+ }
+
+ return sb.toString();
+ }
+
+ @Override
+ public IMXMLTagData findMatchingEndTag()
+ {
+ return findMatchingEndTag(false);
+ }
+
+ /**
+ * Finds the close tag that matches this tag.
+ * <p>
+ * Returns null if this tag is a close or empty tag.
+ * <p>
+ * Returns null if a surrounding tag is unbalanced ONLY if includeImplicit
+ * is false; this is determined by backing up to the innermost parent tag
+ * with a different tag.
+ * <p>
+ * {@code <a> <b> <b> <-- find matching for this one will return null
+ * </b> </a> * }
+ */
+ public IMXMLTagData findMatchingEndTag(boolean includeImplicit)
+ {
+ if (isCloseTag() || isEmptyTag())
+ return null;
+ // Back up to the first surrounding tag that has a different name, and ensure
+ // that *it* is balanced, saving our expected return value along the way.
+ IMXMLTagData startTag = this;
+ while (true)
+ {
+ IMXMLTagData parentTag = startTag.getContainingTag(startTag.getAbsoluteStart());
+ if (parentTag == null)
+ break;
+ startTag = parentTag;
+ if (!parentTag.getName().equals(this.getName()))
+ {
+ break;
+ }
+ }
+ // Now walk through the tags starting at startTag. Once we pop ourselves
+ // off the tagStack, we've found our candidate result -- but keep going
+ // until the stack is null, to ensure that we're balanced out to the
+ // surrounding tag.
+ IMXMLUnitData[] list = getParent().getUnits();
+ FastStack<IMXMLTagData> tagStack = new FastStack<IMXMLTagData>();
+ IMXMLTagData result = null;
+ for (int i = startTag.getIndex(); i < list.length; i++)
+ {
+ IMXMLUnitData curUnit = list[i];
+ if (curUnit.isTag())
+ {
+ IMXMLTagData curTag = (IMXMLTagData)curUnit;
+ if (curTag.isEmptyTag())
+ {
+ // do nothing for empty tags.
+ }
+ else if (curTag.isOpenTag())
+ {
+ tagStack.push(curTag);
+ }
+ else if (curTag.isCloseTag())
+ {
+ if (tagStack.isEmpty())
+ {
+ // document is unbalanced.
+ return null;
+ }
+ IMXMLTagData pop = tagStack.pop();
+
+ //check the short name in case the namespace is not spelled properly
+ if (!pop.getName().equals(curTag.getName()) && !pop.getShortName().equals(curTag.getShortName()))
+ {
+ // document is unbalanced.
+ return null;
+ }
+ if (pop == this)
+ {
+ // This is our result -- remember it.
+ result = curTag;
+ }
+ if (tagStack.isEmpty())
+ {
+ if (result.isImplicit() && !includeImplicit)
+ return null;
+ return result;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isImplicit()
+ {
+ return false;
+ }
+
+ /**
+ * determines if the current tag has an end tag. Will return true if this
+ * tag is a close tag or an end tag. If the document is not balanced, we
+ * will return false. If the end tag was implicit, we will return false
+ *
+ * @return true if this tag has an end tag
+ */
+ public boolean hasEndTag()
+ {
+ if (isCloseTag() || isEmptyTag())
+ return explicitCloseToken;
+ IMXMLTagData tagData = findMatchingEndTag();
+ return tagData != null && !tagData.isImplicit();
+ }
+
+ @Override
+ public IMXMLUnitData getFirstChildUnit()
+ {
+ // If this tag is <foo/> then it has no child units.
+ if (!isOpenAndNotEmptyTag())
+ return null;
+
+ IMXMLUnitData next = getNext();
+
+ // If this tag is followed immediately by its end tag,
+ // as in <foo></foo>, then it has no child units.
+ if (next == findMatchingEndTag())
+ return null;
+
+ // Otherwise, the first child unit is the unit after the tag.
+ return next;
+ }
+
+ @Override
+ public IMXMLTagData getFirstChild(boolean includeEmptyTags)
+ {
+ IMXMLTagData nextTag = null;
+ if (isEmptyTag())
+ return null;
+ if (isOpenTag())
+ {
+ nextTag = getNextTag();
+ }
+ else
+ {
+ // This is a close tag. Start at the corresponding open tag.
+ IMXMLTagData openTag = getContainingTag(getAbsoluteStart());
+ nextTag = openTag.getNextTag();
+ }
+ // Skip any text blocks to find the next actual tag. If it's an open tag,
+ // that is our first child. Otherwise it's a close tag, return null.
+ while (true)
+ {
+ if (nextTag == null || nextTag.isCloseTag())
+ return null;
+ if (nextTag.isOpenAndNotEmptyTag() || (nextTag.isEmptyTag() && includeEmptyTags))
+ return nextTag;
+ nextTag = nextTag.getNextTag();
+ }
+ }
+
+ @Override
+ public IMXMLTagData getNextSibling(boolean includeEmptyTags)
+ {
+ IMXMLTagData nextTag = null;
+ // Be sure we're starting at the close tag, then get the next tag.
+ if (isCloseTag() || isEmptyTag())
+ {
+ nextTag = getNextTag();
+ }
+ else
+ {
+ IMXMLTagData endTag = findMatchingEndTag();
+ if (endTag == null)
+ return null;
+ nextTag = endTag.getNextTag();
+ }
+ while (true)
+ {
+ if (nextTag == null || nextTag.isCloseTag())
+ return null;
+ if (nextTag.isOpenAndNotEmptyTag() || (nextTag.isEmptyTag() && includeEmptyTags))
+ return nextTag;
+ nextTag = nextTag.getNextTag();
+ }
+ }
+
+ /**
+ * Get the start tags for all children of this tag.
+ *
+ * @param includeEmptyTags <code>true</code> if empty tags should be
+ * included.
+ * @return Array of children.
+ */
+ public IMXMLTagData[] getChildren(boolean includeEmptyTags)
+ {
+ ArrayList<IMXMLTagData> children = new ArrayList<IMXMLTagData>();
+ IMXMLTagData child = getFirstChild(includeEmptyTags);
+ while (child != null)
+ {
+ children.add(child);
+ child = child.getNextSibling(includeEmptyTags);
+ }
+ return children.toArray(new IMXMLTagData[0]);
+ }
+
+ /**
+ * Return the parent tag of this tag. If the document is not balanced before
+ * this tag, returns null.
+ */
+ public IMXMLTagData getParentTag()
+ {
+ IMXMLUnitData data = getParentUnitData();
+ if (data instanceof IMXMLTagData)
+ return (IMXMLTagData)data;
+ return null;
+ }
+
+ @Override
+ public ISourceLocation getLocationOfChildUnits()
+ {
+ String sourcePath = getSourcePath();
+ int start = getStart();
+ int end = getEnd();
+ int line = getLine();
+ int column = getColumn();
+
+ boolean foundFirstChild = false;
+
+ for (IMXMLUnitData unit = getFirstChildUnit(); unit != null; unit = unit.getNextSiblingUnit())
+ {
+ if (!foundFirstChild)
+ {
+ sourcePath = unit.getSourcePath();
+ start = unit.getStart();
+ line = unit.getLine();
+ column = unit.getColumn();
+
+ foundFirstChild = true;
+ }
+
+ end = unit.getEnd();
+ }
+
+ return new SourceLocation(sourcePath, start, end, line, column);
+ }
+
+ /**
+ * Verifies that this tag and its attributes have their source location
+ * information set.
+ * <p>
+ * This is used only in asserts.
+ */
+ @Override
+ public boolean verify()
+ {
+ // Verify the source location.
+ super.verify();
+
+ // Verify the attributes.
+ for (IMXMLTagAttributeData attribute : getAttributeDatas())
+ {
+ ((MXMLTagAttributeData)attribute).verify();
+ }
+
+ return true;
+ }
+
+ /**
+ * For debugging only. This format is nice in the Eclipse debugger.
+ */
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append('<');
+ if (isCloseTag())
+ sb.append('/');
+ sb.append(getName());
+ if (isEmptyTag())
+ sb.append('/');
+ sb.append('>');
+
+ sb.append(' ');
+
+ // Display line, column, start, end as "17:5 160-188"
+ sb.append(super.toString());
+
+ // add content range as "(161-187)"
+ sb.append(' ');
+ sb.append('(');
+ sb.append(nameStart);
+ sb.append('-');
+ sb.append(contentEnd);
+ sb.append(')');
+
+ return sb.toString();
+ }
+
+ /**
+ * For debugging only. This format is nice in a text file.
+ */
+ @Override
+ public String toDumpString()
+ {
+ return buildDumpString(false);
+ }
+
+ @Override
+ public String buildDumpString(boolean skipSrcPath)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(super.buildDumpString(skipSrcPath));
+
+ sb.append('\t');
+
+ sb.append('|');
+ sb.append(getName());
+ sb.append('|');
+
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTextData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTextData.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTextData.java
new file mode 100644
index 0000000..c09f7a1
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTextData.java
@@ -0,0 +1,404 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import static org.apache.flex.compiler.constants.IMXMLCoreConstants.*;
+
+import java.util.Collection;
+
+import org.apache.flex.compiler.common.ISourceLocation;
+import org.apache.flex.compiler.internal.parsing.ISourceFragment;
+import org.apache.flex.compiler.internal.parsing.SourceFragment;
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
+import org.apache.flex.compiler.mxml.IMXMLTextData;
+import org.apache.flex.compiler.parsing.MXMLTokenTypes;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+
+/**
+ * Encapsulation of a block of text in MXML
+ */
+public class MXMLTextData extends MXMLUnitData implements IMXMLTextData
+{
+ /**
+ * Constructor.
+ */
+ MXMLTextData(MXMLToken textToken)
+ {
+ text = textToken.getText();
+
+ setOffsets(textToken.getStart(), textToken.getEnd());
+ setLine(textToken.getLine());
+ setColumn(textToken.getColumn());
+
+ switch (textToken.getType())
+ {
+ case MXMLTokenTypes.TOKEN_TEXT:
+ {
+ type = TextType.TEXT;
+ break;
+ }
+ case MXMLTokenTypes.TOKEN_WHITESPACE:
+ {
+ type = TextType.WHITESPACE;
+ break;
+ }
+ case MXMLTokenTypes.TOKEN_CDATA:
+ {
+ type = TextType.CDATA;
+ break;
+ }
+ case MXMLTokenTypes.TOKEN_COMMENT:
+ {
+ type = TextType.COMMENT;
+ break;
+ }
+ case MXMLTokenTypes.TOKEN_ASDOC_COMMENT:
+ {
+ type = TextType.ASDOC;
+ break;
+ }
+ default:
+ {
+ type = TextType.OTHER;
+ break;
+ }
+ }
+ }
+
+ /**
+ * The represented text
+ */
+ private String text;
+
+ private TextType type;
+
+ //
+ // Object overrides
+ //
+
+ // For debugging only. This format is nice in the Eclipse debugger.
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ // Display TEXT, WHITESPACE, etc.
+ sb.append(getTextType());
+
+ sb.append(' ');
+
+ // Display the text characters.
+ sb.append('"');
+ sb.append(getEscapedContent());
+ sb.append('"');
+
+ sb.append(' ');
+
+ // Display line, column, start, and end as "17:5 160-188".
+ sb.append(super.toString());
+
+ return sb.toString();
+ }
+
+ //
+ // MXMLUnitData overrides
+ //
+
+ @Override
+ public boolean isText()
+ {
+ return true;
+ }
+
+ // For debugging only.
+ @Override
+ public String getTypeString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(super.getTypeString());
+ sb.append(":");
+ sb.append(getTextType());
+
+ return sb.toString();
+ }
+
+ // For debugging only. This format is nice in a text file.
+ @Override
+ public String toDumpString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(super.toDumpString());
+
+ sb.append('\t');
+
+ sb.append('|');
+ sb.append(getEscapedContent());
+ sb.append('|');
+
+ return sb.toString();
+ }
+
+ //
+ // IMXMLTextData implementations
+ //
+
+ @Override
+ public String getContent()
+ {
+ return text;
+ }
+
+ @Override
+ public TextType getTextType()
+ {
+ return type;
+ }
+
+ //
+ // Other methods
+ //
+
+ // For debugging only.
+ private String getEscapedContent()
+ {
+ String s = getContent();
+
+ s = s.replaceAll("\n", "\\\\n");
+ s = s.replaceAll("\r", "\\\\r");
+ s = s.replaceAll("\t", "\\\\t");
+
+ return s;
+ }
+
+ @Override
+ public String getCompilableText()
+ {
+ switch (type)
+ {
+ case TEXT:
+ case CDATA:
+ case WHITESPACE:
+ {
+ return getContents();
+ }
+
+ case ASDOC:
+ case COMMENT:
+ {
+ return "";
+ }
+ }
+
+ assert false;
+ return null;
+ }
+
+ @Override
+ public int getCompilableTextStart()
+ {
+ return getContentsStart();
+ }
+
+ @Override
+ public int getCompilableTextEnd()
+ {
+ return getContentsEnd();
+ }
+
+ @Override
+ public int getCompilableTextLine()
+ {
+ return getLine();
+ }
+
+ @Override
+ public int getCompilableTextColumn()
+ {
+ return (getContentsStart() - getAbsoluteStart()) + getColumn();
+ }
+
+ /**
+ * Return the text contained within this unit, without any opening or
+ * closing delimiters
+ *
+ * @return a normalized string
+ */
+ public String getContents()
+ {
+ String tokenString = text;
+
+ switch (type)
+ {
+ case CDATA:
+ {
+ if (tokenString.endsWith(cDataEnd))
+ {
+ tokenString = tokenString.substring(cDataStart.length(), tokenString.length() - cDataEnd.length());
+ }
+ else
+ {
+ tokenString = tokenString.substring(cDataStart.length());
+ }
+ return tokenString;
+ }
+ case ASDOC:
+ {
+ if (tokenString.endsWith(asDocEnd))
+ {
+ tokenString = tokenString.substring(asDocStart.length(), tokenString.length() - asDocEnd.length());
+ }
+ else
+ {
+ tokenString = tokenString.substring(asDocStart.length());
+ }
+ return tokenString;
+ }
+ case COMMENT:
+ {
+ if (tokenString.endsWith(commentEnd))
+ {
+ tokenString = tokenString.substring(commentStart.length(), tokenString.length() - commentEnd.length());
+ }
+ else
+ {
+ tokenString = tokenString.substring(commentStart.length());
+ }
+ return tokenString;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return text;
+ }
+
+ /**
+ * @return The start offset of actual content
+ */
+ public int getContentsStart()
+ {
+ switch (type)
+ {
+ case CDATA:
+ return getAbsoluteStart() + cDataStart.length();
+
+ case ASDOC:
+ return getAbsoluteStart() + asDocStart.length();
+
+ case COMMENT:
+ return getAbsoluteStart() + commentStart.length();
+
+ case OTHER:
+ return getAbsoluteStart();
+ }
+
+ return getAbsoluteStart();
+ }
+
+ /**
+ * @return The end offset of content
+ */
+ public int getContentsEnd()
+ {
+ switch (type)
+ {
+ case CDATA:
+ return text.endsWith(cDataEnd) ? getAbsoluteEnd() - cDataEnd.length() : getAbsoluteEnd();
+
+ case ASDOC:
+ return text.endsWith(asDocEnd) ? getAbsoluteEnd() - asDocEnd.length() : getAbsoluteEnd();
+
+ case COMMENT:
+ return text.endsWith(commentEnd) ? getAbsoluteEnd() - commentEnd.length() : getAbsoluteEnd();
+
+ case OTHER:
+ return getAbsoluteEnd();
+ }
+
+ return getAbsoluteEnd();
+ }
+
+ public int getContentsLine()
+ {
+ return getLine();
+ }
+
+ public int getContentsColumn()
+ {
+ switch (type)
+ {
+ case CDATA:
+ return getColumn() + cDataStart.length();
+
+ case ASDOC:
+ return getColumn() + asDocStart.length();
+
+ case COMMENT:
+ return getColumn() + commentStart.length();
+
+ case OTHER:
+ return getColumn();
+ }
+
+ return getColumn();
+ }
+
+ @Override
+ public ISourceFragment[] getFragments(Collection<ICompilerProblem> problems)
+ {
+ ISourceLocation location = this;
+
+ switch (type)
+ {
+ case TEXT:
+ {
+ // TEXT might contain one or more entities,
+ // in which case we will return multiple fragments.
+ MXMLDialect mxmlDialect = getMXMLDialect();
+ return EntityProcessor.parse(text, location, mxmlDialect, problems);
+ }
+
+ case WHITESPACE:
+ {
+ // WHITESPACE creates only a single fragment.
+ ISourceFragment fragment = new SourceFragment(text, location);
+ return new ISourceFragment[] {fragment};
+ }
+
+ case CDATA:
+ {
+ // CDATA creates only a single fragment.
+ ISourceFragment fragment = new SourceFragment(text, getContents(), getContentsStart(), getContentsLine(), getContentsColumn());
+ return new ISourceFragment[] {fragment};
+ }
+
+ default:
+ {
+ assert false : "Unexpected type of MXMLTextData";
+ }
+ }
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTextValue.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTextValue.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTextValue.java
new file mode 100644
index 0000000..790aa7a
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTextValue.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
+import org.apache.flex.compiler.mxml.IMXMLTagAttributeData;
+import org.apache.flex.compiler.mxml.IMXMLTextValue;
+import org.apache.flex.compiler.mxml.IMXMLTextData.TextType;
+
+public class MXMLTextValue extends MXMLTagAttributeValue implements
+ IMXMLTextValue
+{
+ /**
+ * Constructor.
+ */
+ MXMLTextValue(MXMLToken textToken, IMXMLTagAttributeData parent)
+ {
+ super(parent);
+ setStart(textToken.getStart());
+ setEnd(textToken.getEnd());
+ setColumn(textToken.getColumn());
+ setLine(textToken.getLine());
+ text = textToken.getText();
+ }
+
+ private String text;
+
+ //
+ // Object overrides
+ //
+
+ /**
+ * For debugging only. This format is nice in the Eclipse debugger.
+ */
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("|");
+ sb.append(getContent());
+ sb.append("| ");
+ sb.append(getLine());
+ sb.append(" ");
+ sb.append(getColumn());
+
+ return sb.toString();
+ }
+
+ //
+ // IMXMLTextData implementations
+ //
+
+ @Override
+ public String getContent()
+ {
+ return text;
+ }
+
+ @Override
+ public TextType getTextType()
+ {
+ return TextType.TEXT;
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLUnitData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLUnitData.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLUnitData.java
new file mode 100644
index 0000000..0bd07ec
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLUnitData.java
@@ -0,0 +1,366 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import org.apache.flex.compiler.common.SourceLocation;
+import org.apache.flex.compiler.filespecs.FileSpecification;
+import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.mxml.IMXMLData;
+import org.apache.flex.compiler.mxml.IMXMLTagData;
+import org.apache.flex.compiler.mxml.IMXMLUnitData;
+import org.apache.flex.utils.FastStack;
+
+/**
+ * Encapsulation of an MXML unit: an open/close/empty tag, a chunk of text
+ * (perhaps whitespace, CDATA, or a comment), or a processing instruction.
+ * <p>
+ * An {@link MXMLData} object stores a linear list of MXML units, but it is
+ * possible to walk them in a hierarchical way.
+ */
+public abstract class MXMLUnitData extends SourceLocation implements
+ IMXMLUnitData
+{
+ /**
+ * Constructor.
+ */
+ public MXMLUnitData()
+ {
+ super();
+
+ parent = null;
+ index = -1;
+ }
+
+ /**
+ * Copy constructor.
+ */
+ public MXMLUnitData(MXMLUnitData other)
+ {
+ this.parent = other.parent;
+ this.index = other.index;
+ }
+
+ /**
+ * The {@link MXMLData} object that owns this unit.
+ */
+ private MXMLData parent;
+
+ /**
+ * This position of this unit in the linear list of units owned by the
+ * {@link MXMLData}.
+ */
+ protected int index;
+
+ /**
+ * The position of this unit's parent unit in the linear list of units owned
+ * by the {@link MXMLData}.
+ */
+ private int parentIndex;
+
+ @Override
+ public int getContentStart()
+ {
+ return getAbsoluteStart();
+ }
+
+ @Override
+ public int getContentEnd()
+ {
+ return getAbsoluteEnd();
+ }
+
+ /**
+ * Set this unit's position relative to its parent. Used in parsing.
+ *
+ * @param parent MXML file containing the unit
+ * @param index this unit's position in the list
+ */
+ public void setLocation(MXMLData parent, int index)
+ {
+ this.parent = parent;
+ this.index = index;
+ setSourcePath(parent.getPath());
+ }
+
+ /**
+ * Sets the index of this tags hierarchical parent in its parents array of
+ * MXMLUnitData objects
+ *
+ * @param parentIndex The index of the parent tag.
+ */
+ public void setParentUnitDataIndex(int parentIndex)
+ {
+ this.parentIndex = parentIndex;
+ }
+
+ @Override
+ public final IMXMLUnitData getParentUnitData()
+ {
+ return parent.getUnit(parentIndex);
+ }
+
+ /**
+ * Gets the index of this tags hierarchical parent in its parents array of
+ * MXMLUnitData objects
+ *
+ * @return the index, or -1
+ */
+ public final int getParentUnitDataIndex()
+ {
+ return parentIndex;
+ }
+
+ /**
+ * Set this unit's start and end offsets. Used in parsing.
+ *
+ * @param start start offset
+ * @param end end offset
+ */
+ public void setOffsets(int start, int end)
+ {
+ setStart(start);
+ setEnd(end);
+ }
+
+ /**
+ * Adjust all associated offsets by the adjustment amount
+ *
+ * @param offsetAdjustment amount to add to offsets
+ */
+ public void adjustOffsets(int offsetAdjustment)
+ {
+ setStart(getAbsoluteStart() + offsetAdjustment);
+ setEnd(getAbsoluteEnd() + offsetAdjustment);
+ }
+
+ @Override
+ public final IFileSpecification getSource()
+ {
+ return new FileSpecification(getParent().getPath().toString());
+ }
+
+ @Override
+ public final int getIndex()
+ {
+ return index;
+ }
+
+ @Override
+ public boolean isText()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isTag()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isOpenTag()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isOpenAndNotEmptyTag()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isCloseTag()
+ {
+ return false;
+ }
+
+ @Override
+ public final IMXMLData getParent()
+ {
+ return parent;
+ }
+
+ @Override
+ public final IMXMLUnitData getPrevious()
+ {
+ return parent.getUnit(index - 1);
+ }
+
+ @Override
+ public final IMXMLUnitData getNext()
+ {
+ return parent.getUnit(index + 1);
+ }
+
+ @Override
+ public final IMXMLUnitData getNextSiblingUnit()
+ {
+ IMXMLUnitData unit = this;
+
+ if (isOpenAndNotEmptyTag())
+ unit = ((IMXMLTagData)unit).findMatchingEndTag();
+
+ if (unit != null)
+ {
+ unit = unit.getNext();
+
+ if (unit != null && (unit.getParentUnitData() != getParentUnitData()))
+ unit = null;
+ }
+ return unit;
+ }
+
+ @Override
+ public final IMXMLTagData getNextTag()
+ {
+ IMXMLUnitData nextUnit = getNext();
+
+ while (true)
+ {
+ if (nextUnit == null)
+ return null;
+
+ if (nextUnit.isTag())
+ return (IMXMLTagData)nextUnit;
+
+ nextUnit = nextUnit.getNext();
+ }
+ }
+
+ @Override
+ public boolean containsOffset(int offset)
+ {
+ return MXMLData.contains(getAbsoluteStart(), getAbsoluteEnd(), offset);
+ }
+
+ @Override
+ public final IMXMLTagData getContainingTag(int offset)
+ {
+ FastStack<String> tagNames = new FastStack<String>();
+ IMXMLUnitData current = getPrevious();
+ IMXMLTagData containingTag = null;
+
+ if (containsOffset(offset) && isCloseTag())
+ {
+ IMXMLTagData tag = (IMXMLTagData)this;
+ tagNames.push(tag.getName());
+ }
+
+ while (current != null && containingTag == null)
+ {
+ if (current.isTag())
+ {
+ IMXMLTagData currentTag = (IMXMLTagData)current;
+
+ if (currentTag.isCloseTag())
+ {
+ tagNames.push(currentTag.getName());
+ }
+ else if (currentTag.isOpenTag() && !currentTag.isEmptyTag())
+ {
+ String stackName = "";
+ while (stackName.compareTo(currentTag.getName()) != 0 && !tagNames.isEmpty())
+ {
+ stackName = tagNames.pop();
+ }
+ if (stackName.compareTo(currentTag.getName()) != 0)
+ containingTag = currentTag;
+ }
+ }
+
+ current = current.getPrevious();
+ }
+
+ return containingTag;
+ }
+
+ @Override
+ public MXMLDialect getMXMLDialect()
+ {
+ return getParent().getMXMLDialect();
+ }
+
+ protected String getTypeString()
+ {
+ return getClass().getSimpleName();
+ }
+
+ /**
+ * For debugging only. This format is nice in a text file.
+ */
+ public String toDumpString()
+ {
+ return buildDumpString(false);
+ }
+
+ public String buildDumpString(boolean skipSrcPath)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append('[');
+ sb.append(getIndex());
+ sb.append(']');
+
+ sb.append('\t');
+ if (!skipSrcPath)
+ {
+ sb.append(getLine() + 1);
+ sb.append('\t');
+ sb.append(getColumn() + 1);
+ sb.append('\t');
+ }
+ sb.append(getAbsoluteStart());
+ sb.append('\t');
+ sb.append(getAbsoluteEnd());
+ sb.append('\t');
+
+ String type = getTypeString();
+ sb.append(type);
+ int n = 32 - type.length();
+ for (int i = 0; i < n; i++)
+ sb.append(' ');
+ sb.append('\t');
+
+ sb.append('^');
+ sb.append('[');
+ sb.append(parentIndex);
+ sb.append(']');
+
+ return sb.toString();
+ }
+
+ /**
+ * Verifies that this unit has its source location information set.
+ * <p>
+ * This is used only in asserts.
+ */
+ public boolean verify()
+ {
+ // Verify the source location.
+ assert getSourcePath() != null : "MXMLUnitData has null source path: " + toString();
+ assert getStart() != UNKNOWN : "MXMLUnitData has unknown start: " + toString();
+ assert getEnd() != UNKNOWN : "MXMLUnitData has unknown end: " + toString();
+ assert getLine() != UNKNOWN : "MXMLUnitData has unknown line: " + toString();
+ assert getColumn() != UNKNOWN : "MXMLUnitData has unknown column: " + toString();
+
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/StateDefinition.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/StateDefinition.java b/compiler/src/org/apache/flex/compiler/internal/mxml/StateDefinition.java
new file mode 100644
index 0000000..f8af599
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/StateDefinition.java
@@ -0,0 +1,93 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.flex.compiler.mxml.IStateDefinition;
+import org.apache.flex.compiler.mxml.IStateGroupDefinition;
+import org.apache.flex.compiler.scopes.IASScope;
+import org.apache.flex.compiler.tree.mxml.IMXMLStateNode;
+
+/**
+ * {@code StateDefinition} represents a state in MXML 2009 or later. States are
+ * per-class, so these objects are owned by the {@code ClassDefinitionNodes}
+ * that define classes in MXML.
+ */
+public class StateDefinition extends StateDefinitionBase implements
+ IStateDefinition
+{
+ private IMXMLStateNode node;
+
+ /**
+ * Constructor.
+ */
+ public StateDefinition(IMXMLStateNode node, IASScope containingScope, String name, int nameStart, int nameEnd)
+ {
+ super(name, node.getClassDefinitionNode().getDefinition(), containingScope, nameStart, nameEnd);
+ this.node = node;
+ }
+
+ /**
+ * A map mapping group names to {@code IStateGroup} objects. This is
+ * effectively the set of groups that include this state, but we use a map
+ * because we're interested in this set both as a set of group names (the
+ * String keys) and a set of group objects (the {@code IStateGroup} values).
+ */
+ private Map<String, IStateGroupDefinition> groupMap;
+
+ @Override
+ public IMXMLStateNode getNode()
+ {
+ return node;
+ }
+
+ @Override
+ public String[] getStateGroups()
+ {
+ return groupMap != null ? groupMap.keySet().toArray(new String[0]) : new String[0];
+ }
+
+ @Override
+ public IStateGroupDefinition[] resolveStateGroups()
+ {
+ return groupMap.values().toArray(new IStateGroupDefinition[0]);
+ }
+
+ @Override
+ public boolean isIncludedInStateGroup(String group)
+ {
+ return groupMap.containsKey(group);
+ }
+
+ /**
+ * Records that this state belongs to a specified group.
+ *
+ * @param group An {@code IStateGroup} to which this state belongs.
+ */
+ public void addGroup(IStateGroupDefinition group)
+ {
+ if (groupMap == null)
+ groupMap = new HashMap<String, IStateGroupDefinition>(0);
+
+ groupMap.put(group.getBaseName(), group);
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/StateDefinitionBase.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/StateDefinitionBase.java b/compiler/src/org/apache/flex/compiler/internal/mxml/StateDefinitionBase.java
new file mode 100644
index 0000000..db786d9
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/StateDefinitionBase.java
@@ -0,0 +1,75 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import org.apache.flex.compiler.definitions.IClassDefinition;
+import org.apache.flex.compiler.internal.definitions.DefinitionBase;
+import org.apache.flex.compiler.mxml.IStateDefinitionBase;
+import org.apache.flex.compiler.scopes.IASScope;
+
+/**
+ * {@code StateDefinitionBase} is an abstract base class for
+ * {@code StateDefinition} and {@code StateGroupDefinition}, which represent
+ * states and state groups in MXML 2009 and later.
+ */
+public abstract class StateDefinitionBase extends DefinitionBase implements
+ IStateDefinitionBase
+{
+ /**
+ * Constructor.
+ */
+ public StateDefinitionBase(String name, IClassDefinition containingClass, IASScope containingScope, int nameStart, int nameEnd)
+ {
+ super(name);
+ this.containingClass = containingClass;
+ setNameLocation(nameStart, nameEnd);
+ setContainingScope(containingScope);
+ }
+
+ private final IClassDefinition containingClass;
+
+ @Override
+ public boolean isImplicit()
+ {
+ return true; //this node will always be implicit, even though it will have offsets
+ }
+
+ @Override
+ public int compareTo(IStateDefinitionBase other)
+ {
+ return getNameStart() - other.getNameStart();
+ }
+
+ /**
+ * For debugging only.
+ */
+ @Override
+ public String toString()
+ {
+ return getBaseName();
+ }
+
+ @Override
+ public IClassDefinition getContainingClass()
+ {
+ return containingClass;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/StateGroupDefinition.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/StateGroupDefinition.java b/compiler/src/org/apache/flex/compiler/internal/mxml/StateGroupDefinition.java
new file mode 100644
index 0000000..927132b
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/StateGroupDefinition.java
@@ -0,0 +1,84 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.flex.compiler.definitions.IClassDefinition;
+import org.apache.flex.compiler.mxml.IStateDefinition;
+import org.apache.flex.compiler.mxml.IStateGroupDefinition;
+
+/**
+ * {@code StateGroupDefinition} represents a state group in an MXML class.
+ */
+public class StateGroupDefinition extends StateDefinitionBase implements
+ IStateGroupDefinition
+{
+ /**
+ * Constructor.
+ */
+ public StateGroupDefinition(String name, IClassDefinition containingClass)
+ {
+ super(name, containingClass, containingClass.getContainedScope(), -1, -1);
+
+ }
+
+ /**
+ * A map mapping state names to {@code IStateDefinition} objects. This is
+ * effectively the set of states included in this group, but we use a map
+ * because we're interested in this set both as a set of state names (the
+ * String keys) and a set of state objects (the {@code IStateDefinition}
+ * values).
+ */
+ private Map<String, IStateDefinition> stateMap;
+
+ @Override
+ public String[] getIncludedStates()
+ {
+ return stateMap.keySet().toArray(new String[0]);
+ }
+
+ @Override
+ public IStateDefinition[] resolveIncludedStates()
+ {
+ return stateMap.values().toArray(new IStateDefinition[0]);
+ }
+
+ @Override
+ public boolean isStateIncluded(String state)
+ {
+ return stateMap.containsKey(state);
+ }
+
+ /**
+ * Records that this group includes a specified state.
+ *
+ * @param state An {@code IStateDefinition} that this group includes.
+ */
+ public void addState(IStateDefinition state)
+ {
+ if (stateMap == null)
+ stateMap = new HashMap<String, IStateDefinition>(0);
+
+ stateMap.put(state.getBaseName(), state);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/parsing/mxml/MXMLTagDataDepth.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/parsing/mxml/MXMLTagDataDepth.java b/compiler/src/org/apache/flex/compiler/internal/parsing/mxml/MXMLTagDataDepth.java
index 1e4bd8b..1b8e745 100644
--- a/compiler/src/org/apache/flex/compiler/internal/parsing/mxml/MXMLTagDataDepth.java
+++ b/compiler/src/org/apache/flex/compiler/internal/parsing/mxml/MXMLTagDataDepth.java
@@ -28,11 +28,11 @@ import java.util.Map;
import org.apache.flex.compiler.common.PrefixMap;
import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.internal.mxml.MXMLTagData;
import org.apache.flex.compiler.mxml.IMXMLData;
import org.apache.flex.compiler.mxml.IMXMLTagData;
import org.apache.flex.compiler.mxml.IMXMLTagAttributeData;
import org.apache.flex.compiler.mxml.IMXMLUnitData;
-import org.apache.flex.compiler.mxml.MXMLTagData;
import org.apache.flex.compiler.parsing.MXMLTokenTypes;
import org.apache.flex.compiler.problems.ICompilerProblem;
import org.apache.flex.compiler.problems.SyntaxProblem;
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java b/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java
index 1ae3ae9..f5cfd9b 100644
--- a/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java
+++ b/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java
@@ -56,6 +56,7 @@ import org.apache.flex.compiler.internal.definitions.ClassDefinition;
import org.apache.flex.compiler.internal.definitions.PackageDefinition;
import org.apache.flex.compiler.internal.mxml.MXMLDialect;
import org.apache.flex.compiler.internal.mxml.MXMLManifestManager;
+import org.apache.flex.compiler.internal.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.internal.projects.DependencyGraph.Edge;
import org.apache.flex.compiler.internal.scopes.ASProjectScope;
import org.apache.flex.compiler.internal.scopes.ASScope;
@@ -66,7 +67,6 @@ import org.apache.flex.compiler.internal.tree.mxml.MXMLImplicitImportNode;
import org.apache.flex.compiler.internal.workspaces.Workspace;
import org.apache.flex.compiler.mxml.IMXMLLanguageConstants;
import org.apache.flex.compiler.mxml.IMXMLNamespaceMapping;
-import org.apache.flex.compiler.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.projects.IFlexProject;
import org.apache.flex.compiler.scopes.IDefinitionSet;
import org.apache.flex.compiler.targets.ISWCTarget;
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/tree/mxml/MXMLClassDefinitionNode.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/tree/mxml/MXMLClassDefinitionNode.java b/compiler/src/org/apache/flex/compiler/internal/tree/mxml/MXMLClassDefinitionNode.java
index 1159a0e..96093b0 100644
--- a/compiler/src/org/apache/flex/compiler/internal/tree/mxml/MXMLClassDefinitionNode.java
+++ b/compiler/src/org/apache/flex/compiler/internal/tree/mxml/MXMLClassDefinitionNode.java
@@ -37,6 +37,8 @@ import org.apache.flex.compiler.definitions.IClassDefinition.ClassClassification
import org.apache.flex.compiler.definitions.metadata.IMetaTag;
import org.apache.flex.compiler.internal.definitions.ClassDefinition;
import org.apache.flex.compiler.internal.mxml.MXMLDialect;
+import org.apache.flex.compiler.internal.mxml.StateDefinition;
+import org.apache.flex.compiler.internal.mxml.StateGroupDefinition;
import org.apache.flex.compiler.internal.projects.FlexProject;
import org.apache.flex.compiler.internal.scopes.MXMLFileScope;
import org.apache.flex.compiler.internal.scopes.TypeScope;
@@ -46,8 +48,6 @@ import org.apache.flex.compiler.mxml.IMXMLTagAttributeData;
import org.apache.flex.compiler.mxml.IMXMLTagData;
import org.apache.flex.compiler.mxml.IStateDefinition;
import org.apache.flex.compiler.mxml.IStateGroupDefinition;
-import org.apache.flex.compiler.mxml.StateDefinition;
-import org.apache.flex.compiler.mxml.StateGroupDefinition;
import org.apache.flex.compiler.projects.ICompilerProject;
import org.apache.flex.compiler.scopes.IASScope;
import org.apache.flex.compiler.tree.ASTNodeID;
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/tree/mxml/MXMLStateNode.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/tree/mxml/MXMLStateNode.java b/compiler/src/org/apache/flex/compiler/internal/tree/mxml/MXMLStateNode.java
index 8aabdd2..db8658c 100644
--- a/compiler/src/org/apache/flex/compiler/internal/tree/mxml/MXMLStateNode.java
+++ b/compiler/src/org/apache/flex/compiler/internal/tree/mxml/MXMLStateNode.java
@@ -23,11 +23,11 @@ import org.apache.flex.compiler.common.ASModifier;
import org.apache.flex.compiler.common.IMetaInfo;
import org.apache.flex.compiler.constants.INamespaceConstants;
import org.apache.flex.compiler.definitions.IDefinition;
+import org.apache.flex.compiler.internal.mxml.StateDefinition;
import org.apache.flex.compiler.internal.tree.as.NodeBase;
import org.apache.flex.compiler.mxml.IMXMLTagAttributeData;
import org.apache.flex.compiler.mxml.IMXMLTagData;
import org.apache.flex.compiler.mxml.IStateDefinition;
-import org.apache.flex.compiler.mxml.StateDefinition;
import org.apache.flex.compiler.problems.ICompilerProblem;
import org.apache.flex.compiler.problems.MXMLSemanticProblem;
import org.apache.flex.compiler.tree.ASTNodeID;
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/IMXMLData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/IMXMLData.java b/compiler/src/org/apache/flex/compiler/mxml/IMXMLData.java
index 01621db..f5f0fb5 100644
--- a/compiler/src/org/apache/flex/compiler/mxml/IMXMLData.java
+++ b/compiler/src/org/apache/flex/compiler/mxml/IMXMLData.java
@@ -23,6 +23,7 @@ import java.util.Collection;
import org.apache.flex.compiler.common.PrefixMap;
import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.internal.mxml.MXMLData;
import org.apache.flex.compiler.internal.mxml.MXMLDialect;
import org.apache.flex.compiler.problems.ICompilerProblem;
[2/4] Moved MXMLData-related classes into internal package
Posted by go...@apache.org.
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLData.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLData.java
deleted file mode 100644
index 1134bfb..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLData.java
+++ /dev/null
@@ -1,977 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-import org.apache.commons.io.IOUtils;
-
-import org.apache.flex.compiler.common.MutablePrefixMap;
-import org.apache.flex.compiler.common.PrefixMap;
-import org.apache.flex.compiler.filespecs.FileSpecification;
-import org.apache.flex.compiler.filespecs.IFileSpecification;
-import org.apache.flex.compiler.internal.mxml.MXMLDialect;
-import org.apache.flex.compiler.internal.parsing.mxml.BalancingMXMLProcessor;
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLTokenizer;
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLUnitDataIterator;
-import org.apache.flex.compiler.parsing.MXMLTokenTypes;
-import org.apache.flex.compiler.problems.ICompilerProblem;
-import org.apache.flex.compiler.problems.SyntaxProblem;
-import org.apache.flex.utils.FastStack;
-import org.apache.flex.utils.FastStack.IFastStackDecorator;
-
-/**
- * Encapsulation of an MXML file, with individual units for each open tag, close
- * tag, and block of text.
- */
-public class MXMLData implements IMXMLData
-{
-
- private final class TokenizerPayload
- {
- private List<MXMLToken> tokens;
-
- private PrefixMap prefixMap;
-
- public TokenizerPayload(List<MXMLToken> tokens, PrefixMap prefixMap)
- {
- this.tokens = tokens;
- this.prefixMap = prefixMap;
- }
-
- public List<MXMLToken> getMXMLTokens()
- {
- return tokens;
- }
-
- public PrefixMap getPrefixMap()
- {
- return prefixMap;
- }
- }
-
- /**
- * A cursor represents the offset into the document and the index of the
- * MXML unit that contains that offset
- */
- public class Cursor
- {
- /**
- * Offset into the document
- */
- private int offset;
- /**
- * Index of the unit that contains that offset
- */
- private int unitIndex;
-
- /**
- * Constructor (points to beginning of the MXMLData)
- */
- public Cursor()
- {
- reset();
- }
-
- /**
- * Reset cursor to the beginning of the MXMLData
- */
- public void reset()
- {
- offset = 0;
- unitIndex = 0;
- }
-
- /**
- * Set the cursor to a particular offset/unit
- *
- * @param offset offset into the document
- * @param unitIndex index of the unit containing that offset
- */
- public void setCursor(int offset, int unitIndex)
- {
- this.offset = offset;
- this.unitIndex = unitIndex;
- }
-
- /**
- * Get the offset the cursor is pointing to
- *
- * @return current document offset
- */
- public int getOffset()
- {
- return offset;
- }
-
- /**
- * Get the index of the unit the cursor is pointing to
- *
- * @return current unit index
- */
- public int getUnitIndex()
- {
- return unitIndex;
- }
- }
-
- private String path = null;
-
- /**
- * Individual units for each open tag, close tag, and block of text
- */
- private IMXMLUnitData[] units;
-
- /**
- * Flag indicating that the tokens underlying this structure were fixed
- */
- private boolean wasRepaired;
-
- private boolean shouldRepair = true;
-
- /**
- * This maps {@link IMXMLTagData} objects to their explicit
- * {@link PrefixMap} if it exist
- */
- private HashMap<IMXMLTagData, PrefixMap> nsMap;
-
- /**
- * The cursor holds the result of last offset lookup into the MXMLData (see
- * findNearestUnit, below). When an edit happens that causes the code
- * coloring engine to recompute everything from the edit position to the end
- * of the document, it will request MXMLOffsetInformations in order. Having
- * the cursor speeds this up tremendously.
- */
- private Cursor cursor;
-
- /**
- * The dialect of MXML being used.
- */
- private MXMLDialect mxmlDialect;
-
- private Collection<ICompilerProblem> problems = new ArrayList<ICompilerProblem>(2);
-
- /**
- * Tells us if we are currently processing full MXML, or a fragment
- */
- private boolean fullContent = true;
-
- /**
- * Constructor
- *
- * @param tokens MXML tokens to build the MXMLData object from
- * @param map the {@link PrefixMap} for the document, containing the
- * namespace/prefix mappings
- */
- public MXMLData(List<MXMLToken> tokens, PrefixMap map, IFileSpecification fileSpec)
- {
- path = fileSpec.getPath();
- init(tokens, map);
- }
-
- public MXMLData(List<MXMLToken> tokens, PrefixMap map, IFileSpecification fileSpec, boolean shouldRepair)
- {
- path = fileSpec.getPath();
- this.shouldRepair = false;
- init(tokens, map);
- }
-
- /**
- * Constructor
- *
- * @param mxmlText input build our {@link MXMLData} from
- */
- public MXMLData(int startOffset, Reader mxmlText, IFileSpecification fileSpec)
- {
- TokenizerPayload payload = getTokens(startOffset, mxmlText);
- path = fileSpec.getPath();
- init(payload.getMXMLTokens(), payload.getPrefixMap());
- }
-
- /**
- * Constructor
- *
- * @param mxmlText input build our {@link MXMLData} from
- */
- public MXMLData(int startOffset, Reader mxmlText, String path, boolean fullContent)
- {
- this.fullContent = fullContent;
- TokenizerPayload payload = getTokens(startOffset, mxmlText);
- this.path = path;
- init(payload.getMXMLTokens(), payload.getPrefixMap());
- }
-
- public MXMLData(Reader mxmlText, IFileSpecification fileSpec)
- {
- this(0, mxmlText, fileSpec);
- }
-
- public MXMLData(Reader mxmlText, String path)
- {
- // Some clients of MXML data pass in a null IPath for the source path.
- // Specifically this seems to happen in the code that builds a new
- // mxml document from a template.
- this(0, mxmlText, path != null ? path : null, true);
- }
-
- /**
- * Constructor
- *
- * @param specification input build our {@link MXMLData} from
- */
- public MXMLData(IFileSpecification specification)
- {
- TokenizerPayload payload;
- try
- {
- path = specification.getPath();
- payload = getTokens(specification.createReader());
- init(payload.getMXMLTokens(), payload.getPrefixMap());
- }
- catch (FileNotFoundException e)
- {
- //do nothing
- }
- }
-
- private void init(List<MXMLToken> tokens, PrefixMap map)
- {
- mxmlDialect = MXMLDialect.getMXMLDialect(map);
- initializeFromTokens(tokens);
- }
-
- /**
- * Update the version of the mxml data
- *
- * @param map the prefix map
- */
- public void updateMXMLVersion(PrefixMap map)
- {
- mxmlDialect = MXMLDialect.getMXMLDialect(map);
- }
-
- /**
- * Get the namespaces defined on the root tag
- *
- * @param reader The reader which would provide the root tag information
- * @return {@link PrefixMap} for the root tag
- * @throws IOException error
- */
- public static PrefixMap getRootNamespaces(Reader reader) throws IOException
- {
- MXMLTokenizer tokenizer = new MXMLTokenizer();
- try
- {
- tokenizer.setReader(reader);
- return tokenizer.getRootTagPrefixMap().clone();
- }
- finally
- {
- tokenizer.close();
- }
- }
-
- protected TokenizerPayload getTokens(Reader reader)
- {
- return getTokens(0, reader);
- }
-
- protected TokenizerPayload getTokens(int startOffset, Reader reader)
- {
- List<MXMLToken> tokens = null;
- MXMLTokenizer tokenizer = new MXMLTokenizer(startOffset);
- try
- {
- tokenizer.setIsRepairing(true);
- tokens = tokenizer.parseTokens(reader);
- wasRepaired = tokenizer.tokensWereRepaired();
- return new TokenizerPayload(tokens, tokenizer.getPrefixMap());
- }
- finally
- {
- IOUtils.closeQuietly(tokenizer);
- }
- }
-
- @Override
- public MXMLDialect getMXMLDialect()
- {
- return mxmlDialect;
- }
-
- @Override
- public PrefixMap getPrefixMapForData(IMXMLTagData data)
- {
- PrefixMap result = nsMap.get(data);
- if (result != null)
- return result;
- if (data.isCloseTag())
- {
- IMXMLTagData openTagData = data.getParent().findTagOrSurroundingTagContainingOffset(data.getAbsoluteStart());
- if (openTagData != null)
- return nsMap.get(openTagData);
- }
- return null;
- }
-
- void removePrefixMappingForTag(IMXMLTagData data)
- {
- nsMap.remove(data);
- }
-
- void clearPrefixMappings()
- {
- nsMap.clear();
- }
-
- public void setPrefixMappings(HashMap<IMXMLTagData, PrefixMap> map)
- {
- if (nsMap != null)
- nsMap.clear();
- nsMap = map;
- }
-
- public Map<IMXMLTagData, PrefixMap> getTagToPrefixMap()
- {
- return nsMap;
- }
-
- /**
- * Returns a collection of prefix->namespaces mappings found within this
- * document. This map DOES NOT maintain order, and for more fine-grained
- * information, the getPrefixMap call on individual {@link IMXMLTagData} and
- * {@link IMXMLTagAttributeData} objects should be called
- *
- * @return a prefix map
- */
- public PrefixMap getDocumentPrefixMap()
- {
- MutablePrefixMap map = new MutablePrefixMap();
- for (PrefixMap tagMap : nsMap.values())
- {
- assert tagMap != null;
- map.addAll(tagMap);
- }
- return map.toImmutable();
- }
-
- /**
- * Returns the PrefixMap for the root tag of this {@link MXMLData} object
- *
- * @return a {@link PrefixMap} or null
- */
- public PrefixMap getRootTagPrefixMap()
- {
- IMXMLTagData rootTag = getRootTag();
- if (rootTag != null)
- {
- return nsMap.get(rootTag);
- }
- return null;
- }
-
- @Override
- public Collection<ICompilerProblem> getProblems()
- {
- return problems;
- }
-
- public boolean hasProblems()
- {
- return problems.size() > 0;
- }
-
- /**
- * Determines if this data was built from a source that was repaired
- *
- * @return true if the underlying source was repaired
- */
- public boolean isDataRepaired()
- {
- return wasRepaired;
- }
-
- public void setWasRepaired(boolean wasRepaired)
- {
- this.wasRepaired = wasRepaired;
- }
-
- @Override
- public IFileSpecification getFileSpecification()
- {
- return new FileSpecification(path);
- }
-
- @Override
- public String getPath()
- {
- return path;
- }
-
- /**
- * API to change the path after MXMLData creation. An MXMLDocument makes an
- * MXMLData before the actual location is known.
- *
- * @param path is the absolute path to the backing source file
- */
- public void setPath(String path)
- {
- this.path = path;
- }
-
- /**
- * Common code from the two constructors
- *
- * @param tokens A list of MXML tokens.
- */
- protected void initializeFromTokens(List<MXMLToken> tokens)
- {
- cursor = new Cursor();
- parse(this, tokens, mxmlDialect, problems);
- cursor.reset();
- }
-
- /**
- * Use the MXML tokens to build MXMLUnitData.
- *
- * @param data the {@link MXMLData} object
- * @param tokens the list of tokens to build this data from
- * @param dialect the {@link MXMLDialect} we are working against
- * @param incremental true if this data is being built incrementally. All
- * location updates will need to be done outside this element
- */
- private void parse(MXMLData data, List<MXMLToken> tokens, MXMLDialect dialect, Collection<ICompilerProblem> problems)
- {
- ArrayList<MXMLUnitData> units = new ArrayList<MXMLUnitData>(tokens.size() / 6);
- nsMap = new HashMap<IMXMLTagData, PrefixMap>();
- MXMLUnitData unit = null;
- MXMLToken currentComment = null;
- FastStack<Integer> depth = new FastStack<Integer>(tokens.size() / 8);
- IFileSpecification spec = new FileSpecification(data.getPath() != null ? data.getPath() : "");
- depth.setStackDecorator(new IFastStackDecorator<Integer>() {
- @Override
- public Integer decorate(Integer e)
- {
- if (e == null)
- return -1;
- return e;
- }
-
- });
- int index = -1;
- int balancingIndex = 0;
- depth.push(index);
- ListIterator<MXMLToken> tokenIterator = tokens.listIterator();
- BalancingMXMLProcessor processor = new BalancingMXMLProcessor(getFileSpecification(), problems);
- while (tokenIterator.hasNext())
- {
- MXMLToken token = tokenIterator.next();
- switch (token.getType())
- {
- case MXMLTokenTypes.TOKEN_ASDOC_COMMENT:
- currentComment = token;
- //treat this like text.
- unit = new MXMLTextData(token);
- units.add(unit);
- index++;
- if (fullContent)
- {
- unit.setParentUnitDataIndex(depth.peek());
- unit.setLocation(data, index);
- }
- break;
- case MXMLTokenTypes.TOKEN_COMMENT:
- case MXMLTokenTypes.TOKEN_CDATA:
- case MXMLTokenTypes.TOKEN_WHITESPACE:
- //treat this like text.
- unit = new MXMLTextData(token);
- units.add(unit);
- index++;
- if (fullContent)
- {
- unit.setParentUnitDataIndex(depth.peek());
- unit.setLocation(data, index);
- }
- break;
- case MXMLTokenTypes.TOKEN_OPEN_TAG_START:
- unit = new MXMLTagData();
- MutablePrefixMap map = ((MXMLTagData)unit).init(this, token, tokenIterator, dialect, spec, problems);
- ((MXMLTagData)unit).setCommentToken(currentComment);
- currentComment = null;
- units.add(unit);
- index++;
- if (fullContent)
- {
- unit.setParentUnitDataIndex(depth.peek());
- unit.setLocation(data, index);
- if (!((MXMLTagData)unit).isEmptyTag())
- processor.addOpenTag((MXMLTagData)unit, balancingIndex);
- }
- if (map != null)
- nsMap.put((MXMLTagData)unit, map.toImmutable());
- if (!((MXMLTagData)unit).isEmptyTag())
- {
- depth.push(index);
- balancingIndex++;
- }
- break;
- case MXMLTokenTypes.TOKEN_CLOSE_TAG_START:
- unit = new MXMLTagData();
- ((MXMLTagData)unit).init(this, token, tokenIterator, dialect, spec, problems);
- ((MXMLTagData)unit).setCommentToken(currentComment);
- if (!((MXMLTagData)unit).isEmptyTag())
- {
- depth.pop();
- balancingIndex--;
- }
- index++;
- if (fullContent)
- {
- unit.setLocation(data, index);
- unit.setParentUnitDataIndex(depth.peek());
- processor.addCloseTag((MXMLTagData)unit, balancingIndex);
- }
- currentComment = null;
- units.add(unit);
- break;
- case MXMLTokenTypes.TOKEN_TEXT:
- unit = new MXMLTextData(token);
- units.add(unit);
- index++;
- if (fullContent)
- {
- unit.setParentUnitDataIndex(depth.peek());
- unit.setLocation(data, index);
- }
- break;
- case MXMLTokenTypes.TOKEN_MXML_BLOB:
- unit = new MXMLTagBlobData(token);
- units.add(unit);
- index++;
- if (fullContent)
- {
- unit.setParentUnitDataIndex(depth.peek());
- unit.setLocation(data, index);
- }
- break;
- case MXMLTokenTypes.TOKEN_DATABINDING_START:
- unit = new MXMLDatabindingData(token, tokenIterator);
- units.add(unit);
- index++;
- if (fullContent)
- {
- unit.setParentUnitDataIndex(depth.peek());
- unit.setLocation(data, index);
- }
- break;
- case MXMLTokenTypes.TOKEN_PROCESSING_INSTRUCTION:
- unit = new MXMLInstructionData(token);
- units.add(unit);
- index++;
- if (fullContent)
- {
- unit.setParentUnitDataIndex(depth.peek());
- unit.setLocation(data, index);
- }
- break;
- default:
- if (token.isEntity())
- {
- unit = new MXMLEntityData(token);
- units.add(unit);
- index++;
- if (fullContent)
- {
- unit.setParentUnitDataIndex(depth.peek());
- unit.setLocation(data, index);
- }
- break;
- }
- else
- {
- problems.add(new SyntaxProblem(token));
- break;
- }
- }
- }
- this.units = units.toArray(new IMXMLUnitData[0]);
- if (fullContent && shouldRepair)
- {
- this.units = processor.balance(this.units, this, nsMap);
- if (processor.wasRepaired())
- { //repaired, so let's rebuild our prefix maps and tag depths
- refreshPositionData();
- }
- }
- }
-
- /**
- * Used to rebuild the structures inside of the MXMLData, refreshing prefix
- * maps, depth and position data. Should only be used after calls that
- * rebuild the internal structure are called
- */
- public void refreshPositionData()
- {
- FastStack<Integer> depth = new FastStack<Integer>(units.length / 2);
- depth.setStackDecorator(new IFastStackDecorator<Integer>() {
- @Override
- public Integer decorate(Integer e)
- {
- if (e == null)
- return -1;
- return e;
- }
-
- });
- depth.clear();
- depth.push(-1);
- for (int i = 0; i < units.length; i++)
- {
- if (units[i] instanceof IMXMLTagData)
- {
- IMXMLTagData currentTag = (IMXMLTagData)units[i];
- if (currentTag.isCloseTag())
- {
- if (!currentTag.isEmptyTag())
- depth.pop();
- }
- ((MXMLTagData)currentTag).setParentUnitDataIndex(depth.peek());
- ((MXMLTagData)currentTag).setLocation(this, i);
- if (currentTag.isOpenTag())
- {
- if (!currentTag.isEmptyTag())
- {
- depth.push(i);
- }
- }
- }
- else
- {
- ((MXMLUnitData)units[i]).setParentUnitDataIndex(depth.peek());
- ((MXMLUnitData)units[i]).setLocation(this, i);
- }
- }
- }
-
- @Override
- public IMXMLUnitData[] getUnits()
- {
- return units;
- }
-
- public Iterator<IMXMLUnitData> getUnitIterator()
- {
- return new MXMLUnitDataIterator(units);
- }
-
- /**
- * Replace the list of units in this MXMLData.
- *
- * @param units units to add
- */
- public void setUnits(IMXMLUnitData[] units)
- {
- this.units = units;
- }
-
- @Override
- public IMXMLUnitData getUnit(int i)
- {
- if (i < 0 || i >= units.length)
- return null;
- return units[i];
- }
-
- @Override
- public int getNumUnits()
- {
- return units.length;
- }
-
- /**
- * If the offset is contained within an MXML unit, get that unit. If it's
- * not, then get the first unit that follows the offset.
- *
- * @param offset test offset
- * @return unit that contains (or immediately follows) the offset A few
- * subtleties: In Falcon we have endeavored to preserve the existing
- * definition of "nearest", so that for a given MXML file, falcon will find
- * the same "nearest" unit.
- */
-
- protected IMXMLUnitData findNearestUnit(int offset)
- {
-
- // Use the cursor as a fast search hint. But only if the cursor is at or before the
- // are of interest.
- // TODO: do we care that this is not thread safe?
- int startOffset = 0;
- if (cursor.getOffset() <= offset)
- startOffset = cursor.getUnitIndex();
-
- // Sanity check
- if (startOffset < 0 || startOffset >= units.length)
- startOffset = 0;
-
- // Now iterate though the units and find the first one that is acceptable
- IMXMLUnitData ret = null;
- for (int i = startOffset; (i < units.length) && (ret == null); i++)
- {
- IMXMLUnitData unit = units[i];
-
- // unit is a match if it "contains" the offset.
- // We are using a somewhat bizarre form of "contains" here, in that we are
- // using getStart() and getConentEnd(). This asymmetric mismatch is for several reasons:
- // * it's the only way to match the existing (non-falcon) behavior
- // * If our cursor is before the <, we want to match the tag.
- // example: |<foo > will find "foo" as the nearest tag.
- // So we need to use start here (not content start)
- // * If our cursor is between two tags, we want to match the NEXT one, not the previous one
- // example: <bar >|<foo> should match foo, not bar
-
- if (MXMLData.contains(unit.getAbsoluteStart(), unit.getContentEnd(), offset))
- {
- ret = unit;
- }
- // if we find a unit that starts after the offset, then it must
- // be the "first one after", so return it
- else if (unit.getAbsoluteStart() >= offset)
- {
- ret = unit;
- }
- }
-
- // If we found something, update the cursor for the next search
- if (ret != null)
- cursor.setCursor(offset, ret.getIndex());
- return ret;
- }
-
- /**
- * Get the unit that should be referenced when looking at what tags contain
- * this offset (i.e. tags that are opened and not closed before this offset)
- *
- * @param offset test offset
- * @return reference unit for containment searches
- */
- public IMXMLUnitData findContainmentReferenceUnit(int offset)
- {
- return findNearestUnit(offset);
- }
-
- /**
- * Get the unit that contains this offset
- *
- * @param offset test offset
- * @return the containing unit (or null if no unit contains this offset)
- */
- public IMXMLUnitData findUnitContainingOffset(int offset)
- {
- IMXMLUnitData unit = findNearestUnit(offset);
- if (unit != null && unit.containsOffset(offset))
- return unit;
-
- return null;
- }
-
- /**
- * Get the open, close, or empty tag that contains this offset. Note that if
- * offset is inside a text node, this returns null. If you want the
- * surrounding tag in that case, use
- * findTagOrSurroundingTagContainingOffset.
- *
- * @param offset test offset
- * @return the containing tag (or null, if no tag contains this offset)
- */
- public IMXMLTagData findTagContainingOffset(int offset)
- {
- IMXMLUnitData unit = findUnitContainingOffset(offset);
- if (unit != null && unit.isTag())
- return (IMXMLTagData)unit;
-
- return null;
- }
-
- @Override
- public IMXMLTagData findTagOrSurroundingTagContainingOffset(int offset)
- {
- IMXMLUnitData unit = findUnitContainingOffset(offset);
- if (unit != null)
- {
- if (unit.isTag())
- {
- return (IMXMLTagData)unit;
- }
- else if (unit.isText())
- {
- IMXMLTagData containingTag = unit.getContainingTag(unit.getAbsoluteStart());
- return containingTag;
- }
- }
-
- return null;
- }
-
- /**
- * Get the open or empty tag whose attribute list contains this offset. A
- * tag's attribute list extends from after the tag name + first whitespace
- * until before the closing ">" or "/>".
- *
- * @param offset test offset
- * @return tag whose attribute list contains this offset (or null, if the
- * offset isn't in any attribute lists
- */
- public IMXMLTagData findAttributeListContainingOffset(int offset)
- {
- IMXMLTagData tag = findTagContainingOffset(offset);
- if (tag != null && tag.isOpenTag())
- return tag.isOffsetInAttributeList(offset) ? tag : null;
-
- return null;
- }
-
- /**
- * Test whether the offset is contained within the range from start to end.
- * This test excludes the start position and includes the end position,
- * which is how you want things to work for code hints.
- *
- * @param start start of the range (excluded)
- * @param end end of the range (included)
- * @param offset test offset
- * @return true iff the offset is contained in the range
- */
- public static boolean contains(int start, int end, int offset)
- {
- return start < offset && end >= offset;
- }
-
- @Override
- public IMXMLTagData getRootTag()
- {
- int n = units.length;
- for (int i = 0; i < n; i++)
- {
- IMXMLUnitData unit = units[i];
- if (unit instanceof IMXMLTagData)
- return (IMXMLTagData)unit;
- }
- return null;
- }
-
- @Override
- public int getEnd()
- {
- final int n = getNumUnits();
- return n > 0 ? getUnit(n - 1).getAbsoluteEnd() : 0;
- }
-
- public Cursor getCursor()
- {
- return cursor;
- }
-
- /**
- * Verifies that all units (plus all attributes on units that are tags) have
- * their source location information set.
- * <p>
- * This is used only in asserts.
- */
- public boolean verify()
- {
- for (IMXMLUnitData unit : getUnits())
- {
- ((MXMLUnitData)unit).verify();
- }
-
- return true;
- }
-
- // For debugging only.
- void dumpUnits()
- {
- for (IMXMLUnitData unit : getUnits())
- {
- System.out.println(((MXMLUnitData)unit).toDumpString());
- }
- }
-
- /**
- * For debugging only.
- */
- @Override
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
-
- IMXMLUnitData[] units = getUnits();
- int n = units.length;
- for (int i = 0; i < n; i++)
- {
- // Display the unit's index as, for example, [3].
- sb.append('[');
- sb.append(i);
- sb.append(']');
-
- sb.append(' ');
-
- // Display the unit's information.
- sb.append(units[i].toString());
-
- sb.append('\n');
- }
-
- return sb.toString();
- }
-
- public static void main(String[] args)
- {
- final FileSpecification fileSpec = new FileSpecification(args[0]);
- final MXMLTokenizer tokenizer = new MXMLTokenizer(fileSpec);
- List<MXMLToken> tokens = null;
- try
- {
- tokens = tokenizer.parseTokens(fileSpec.createReader());
-
- // Build tags and attributes from the tokens.
- final MXMLData mxmlData = new MXMLData(tokens, tokenizer.getPrefixMap(), fileSpec);
-
- mxmlData.dumpUnits();
- }
- catch (FileNotFoundException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- finally
- {
- IOUtils.closeQuietly(tokenizer);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLDatabindingData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLDatabindingData.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLDatabindingData.java
deleted file mode 100644
index 6647263..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLDatabindingData.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import java.util.ListIterator;
-
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
-import org.apache.flex.compiler.parsing.IASToken;
-
-/**
- * Represents a databinding expression found within content of MXML
- */
-public class MXMLDatabindingData extends MXMLUnitData implements
- IMXMLDatabindingData
-{
- /**
- * Constructor.
- */
- MXMLDatabindingData(MXMLToken start, ListIterator<MXMLToken> iterator)
- {
- bindingValue = new MXMLDatabindingValue(start, iterator);
-
- setOffsets(bindingValue.getAbsoluteStart(), bindingValue.getAbsoluteEnd());
- setLine(start.getLine());
- setColumn(start.getColumn());
- }
-
- private IMXMLDatabindingValue bindingValue;
-
- //
- // IMXMLDatabindingData implementations
- //
-
- @Override
- public IASToken[] getDatabindingContent()
- {
- return bindingValue.getDatabindingContent();
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLDatabindingValue.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLDatabindingValue.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLDatabindingValue.java
deleted file mode 100644
index ab24ad7..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLDatabindingValue.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import java.util.ArrayList;
-import java.util.ListIterator;
-
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
-import org.apache.flex.compiler.mxml.IMXMLTextData.TextType;
-import org.apache.flex.compiler.parsing.IASToken;
-
-/**
- * Represents a databinding expression found within an attribute value
- */
-public class MXMLDatabindingValue extends MXMLTagAttributeValue implements
- IMXMLDatabindingValue
-{
- /**
- * Constructor.
- */
- MXMLDatabindingValue(MXMLToken start, ListIterator<MXMLToken> iterator, IMXMLTagAttributeData parent)
- {
- super(parent);
-
- setStart(start.getStart());
- setColumn(start.getColumn());
- setLine(start.getLine());
-
- while (iterator.hasNext())
- {
- MXMLToken token = iterator.next();
-
- setEnd(token.getEnd());
-
- if (token.isASToken())
- tokens.add(token);
- else
- break;
- }
- }
-
- /**
- * Constructor.
- */
- MXMLDatabindingValue(MXMLToken start, ListIterator<MXMLToken> iterator)
- {
- this(start, iterator, null);
- }
-
- private ArrayList<IASToken> tokens = new ArrayList<IASToken>(5);
-
- //
- // IMXMLTextData implementations
- //
-
- @Override
- public String getContent()
- {
- StringBuilder builder = new StringBuilder();
-
- final int size = tokens.size();
- IASToken lastToken = null;
- for (int i = 0; i < size; i++)
- {
- IASToken currentToken = tokens.get(i);
- if (lastToken != null)
- {
- int spaces = currentToken.getStart() - lastToken.getEnd();
- for (int s = 0; s < spaces; s++)
- builder.append(" ");
- }
- builder.append(currentToken.getText());
- lastToken = currentToken;
- }
-
- return builder.toString();
- }
-
- @Override
- public TextType getTextType()
- {
- return TextType.DATABINDING;
- }
-
- //
- // IMXMLDatabindingData implementations
- //
-
- @Override
- public IASToken[] getDatabindingContent()
- {
- return tokens.toArray(new IASToken[0]);
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLEntityData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLEntityData.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLEntityData.java
deleted file mode 100644
index 376af19..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLEntityData.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
-
-public class MXMLEntityData extends MXMLTextData implements IMXMLEntityData
-{
- /**
- * Constructor.
- */
- MXMLEntityData(MXMLToken textToken)
- {
- super(textToken);
-
- type = textToken.getType();
- }
-
- private int type;
-
- //
- // Object overrides
- //
-
- // This method is only used for debugging.
- @Override
- public String toString()
- {
- String s = getCompilableText();
-
- s = s.replaceAll("\n", "\\\\n");
- s = s.replaceAll("\r", "\\\\r");
- s = s.replaceAll("\t", "\\\\t");
-
- StringBuilder sb = new StringBuilder();
- sb.append(type);
- sb.append(" \"");
- sb.append(s);
- sb.append("\"");
- return sb.toString();
- }
-
- //
- // MXMLTextData overrides
- //
-
- @Override
- public String getCompilableText()
- {
- return getDecodedContent();
- }
-
- //
- // IMXMLEntityData implementations
- //
-
- @Override
- public String getDecodedContent()
- {
- return MXMLEntityValue.getDecodedContent(getContents(), type);
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLEntityValue.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLEntityValue.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLEntityValue.java
deleted file mode 100644
index 68e6a70..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLEntityValue.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.flex.compiler.mxml.IMXMLTextData.TextType;
-import org.apache.flex.compiler.parsing.IMXMLToken;
-import org.apache.flex.compiler.parsing.MXMLTokenTypes;
-
-public class MXMLEntityValue extends MXMLTagAttributeValue implements
- IMXMLEntityValue
-{
- private static final Map<String, String> NAMED_ENTITIES;
-
- static
- {
- NAMED_ENTITIES = new HashMap<String, String>(5);
-
- NAMED_ENTITIES.put("&", "&");
- NAMED_ENTITIES.put("'", "'");
- NAMED_ENTITIES.put(">", ">");
- NAMED_ENTITIES.put("<", "<");
- NAMED_ENTITIES.put(""", "\"");
-
- // TODO HTML 4 supports about 250 named characters
- // HTML 5 supports about 2500. How many should MXML support
- // beyond these required 5? What did Xerces/mxmlc support?
- }
-
- static final String getDecodedContent(String content, int type)
- {
- switch (type)
- {
- case MXMLTokenTypes.TOKEN_ENTITY:
- {
- return NAMED_ENTITIES.get(content);
- }
- case MXMLTokenTypes.TOKEN_HEX_ENTITY:
- {
- //thanks to the lexer, we are always: �
- //strip off the first 3 chars and the trailing semicolon
- return String.valueOf(Integer.parseInt(content.substring(3, content.length() - 1), 16));
- }
- case MXMLTokenTypes.TOKEN_DECIMAL_ENTITY:
- {
- //thanks to the lexer, we are always: &#\21267;
- //strip off the first 3 chars and the trailing semicolon
- return String.valueOf(Integer.parseInt(content.substring(3, content.length() - 1)));
- }
- }
-
- return null;
- }
-
- /**
- * Constructor.
- */
- MXMLEntityValue(IMXMLToken token, IMXMLTagAttributeData parent)
- {
- super(parent);
-
- content = token.getText();
- type = token.getType();
-
- setStart(token.getStart());
- setEnd(token.getEnd());
- setColumn(token.getColumn());
- setLine(token.getLine());
- }
-
- private final String content;
-
- /**
- * Token type which tells us what kind of entity we are dealing with
- */
- private final int type;
-
- //
- // Object overrides
- //
-
- // For debugging only. This format is nice in the Eclipse debugger.
- @Override
- public String toString()
- {
- StringBuilder sb = new StringBuilder();
-
- sb.append("|");
- sb.append(getContent());
- sb.append("| ");
- sb.append(getLine());
- sb.append(" ");
- sb.append(getColumn());
-
- return sb.toString();
- }
-
- //
- // IMXMLTagAttributeValue implementations
- //
-
- @Override
- public String getContent()
- {
- return content;
- }
-
- @Override
- public TextType getTextType()
- {
- return TextType.ENTITY;
- }
-
- //
- // IMXMLEntityValue implementations
- //
-
- @Override
- public String getDecodedContent()
- {
- return getDecodedContent(content, type);
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLInstructionData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLInstructionData.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLInstructionData.java
deleted file mode 100644
index aca282c..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLInstructionData.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import org.apache.flex.compiler.parsing.IMXMLToken;
-
-public class MXMLInstructionData extends MXMLUnitData implements
- IMXMLInstructionData
-{
- /**
- * Constructor.
- */
- MXMLInstructionData(IMXMLToken token)
- {
- instructionText = token.getText();
-
- setOffsets(token.getStart(), token.getEnd());
- setColumn(token.getColumn());
- setLine(token.getLine());
- }
-
- private String instructionText;
-
- //
- // Object overrides
- //
-
- // For debugging only. This format is nice in the Eclipse debugger.
- @Override
- public String toString()
- {
- StringBuilder sb = new StringBuilder();
-
- sb.append('|');
- sb.append(getInstructionText());
- sb.append('|');
-
- sb.append(' ');
-
- // Display line, column, start, and end as "17:5 160-188".
- sb.append(super.toString());
-
- return sb.toString();
- }
-
- //
- // MXMLUnitData overrides
- //
-
- // For debugging only. This format is nice in a text file.
- @Override
- public String toDumpString()
- {
- StringBuilder sb = new StringBuilder();
-
- sb.append(super.toDumpString());
-
- sb.append('\t');
-
- sb.append('"');
- sb.append(getInstructionText());
- sb.append('"');
-
- return sb.toString();
- }
-
- //
- // IMXMLInstructionData implementations
- //
-
- /**
- * Returns the raw processing instruction. It is up to clients to parse
- * this.
- */
- public String getInstructionText()
- {
- return instructionText;
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLNamespaceAttributeData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLNamespaceAttributeData.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLNamespaceAttributeData.java
deleted file mode 100644
index 90a42f0..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLNamespaceAttributeData.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import java.util.Collection;
-import java.util.ListIterator;
-
-import org.apache.flex.compiler.filespecs.IFileSpecification;
-import org.apache.flex.compiler.internal.mxml.MXMLDialect;
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
-import org.apache.flex.compiler.problems.ICompilerProblem;
-
-/**
- * Represents an xmlns style namespace import found within the MXML language
- */
-public class MXMLNamespaceAttributeData extends MXMLTagAttributeData implements
- IMXMLNamespaceAttributeData
-{
- /**
- * Constructor.
- */
- MXMLNamespaceAttributeData(MXMLToken nameToken, ListIterator<MXMLToken> tokenIterator, MXMLDialect mxmlDialect, IFileSpecification spec, Collection<ICompilerProblem> problems)
- {
- super(nameToken, tokenIterator, mxmlDialect, spec, problems);
-
- if (attributeName.startsWith("xmlns:"))
- prefix = attributeName.substring(6);
- }
-
- private String prefix = "";
-
- //
- // IMXMLNamepsaceAttributeData implementations
- //
-
- @Override
- public String getNamespacePrefix()
- {
- return prefix;
- }
-
- @Override
- public String getNamespace()
- {
- return getRawValue();
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLNamespaceMapping.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLNamespaceMapping.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLNamespaceMapping.java
deleted file mode 100644
index d6c4292..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLNamespaceMapping.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-/**
- * This class stores a MXML-namespace-URI-to-manifest-file mapping.
- */
-public class MXMLNamespaceMapping implements IMXMLNamespaceMapping
-{
- public MXMLNamespaceMapping(String uri, String manifestFileName)
- {
- assert uri != null;
- assert manifestFileName != null;
- this.uri = uri;
- this.manifestFileName = manifestFileName;
- }
-
- private String uri;
- private String manifestFileName;
-
- @Override
- public String getURI()
- {
- return uri;
- }
-
- @Override
- public String getManifestFileName()
- {
- return manifestFileName;
- }
-
- /**
- * For debugging.
- *
- * @return Debug string representation of this object.
- */
- @Override
- public String toString()
- {
- return uri + "->" + manifestFileName;
- }
-
- @Override
- public boolean equals(Object obj)
- {
- if (obj == this)
- return true;
- if (!(obj instanceof MXMLNamespaceMapping))
- return false;
- MXMLNamespaceMapping other = (MXMLNamespaceMapping)obj;
- if (!(uri.equals(other.uri)))
- return false;
- return manifestFileName.equals(other.manifestFileName);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLStateSplitter.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLStateSplitter.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLStateSplitter.java
deleted file mode 100644
index 0631088..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLStateSplitter.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import java.util.Collection;
-
-import org.apache.flex.compiler.filespecs.IFileSpecification;
-import org.apache.flex.compiler.internal.mxml.MXMLDialect;
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
-import org.apache.flex.compiler.parsing.IMXMLToken;
-import org.apache.flex.compiler.problems.ICompilerProblem;
-import org.apache.flex.compiler.problems.SyntaxProblem;
-
-/**
- * Simple utility for parsing attribute.state phrases.
- */
-public class MXMLStateSplitter
-{
- /**
- * Constructor.
- */
- public MXMLStateSplitter(IMXMLToken nameToken, MXMLDialect mxmlDialect, Collection<ICompilerProblem> problems, IFileSpecification fileSpec)
- {
- // Is there a dot in the name?
- String name = nameToken.getText();
- int i = name.indexOf('.');
- if (i >= 0)
- {
- if (mxmlDialect != null && mxmlDialect.isEqualToOrAfter(MXMLDialect.MXML_2009))
- {
- baseName = name.substring(0, i);
- stateName = name.substring(i + 1);
- stateNameOffset = i + 1;
- }
- else
- {
- stateNameOffset = -1;
- baseName = name;
- stateName = null;
-
- // TODO: I don't think is going to make the right kind of "problem"
- // This is how the old code worked, but I think it will give a strange message
- if (problems != null && fileSpec != null)
- problems.add(new SyntaxProblem((MXMLToken)nameToken, "Spark state overrides not supported by current language version"));
- }
- }
- else
- {
- // no dot.
- baseName = name;
- stateNameOffset = -1;
- stateName = null;
- }
- }
-
- /**
- * The part of the name before the dot, or the whole name if no dot.
- */
- public final String baseName;
-
- /**
- * What's after the first dot (state override), or null if no dot
- */
- public final String stateName;
-
- /**
- * offset of state name, where zero is the first character in the name
- */
- public final int stateNameOffset;
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLTagAttributeData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLTagAttributeData.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLTagAttributeData.java
deleted file mode 100644
index 0729af6..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLTagAttributeData.java
+++ /dev/null
@@ -1,635 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.ListIterator;
-
-import org.apache.flex.compiler.common.ISourceLocation;
-import org.apache.flex.compiler.common.PrefixMap;
-import org.apache.flex.compiler.common.SourceLocation;
-import org.apache.flex.compiler.common.XMLName;
-import org.apache.flex.compiler.filespecs.IFileSpecification;
-import org.apache.flex.compiler.internal.mxml.EntityProcessor;
-import org.apache.flex.compiler.internal.mxml.MXMLDialect;
-import org.apache.flex.compiler.internal.parsing.ISourceFragment;
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
-import org.apache.flex.compiler.parsing.IMXMLToken;
-import org.apache.flex.compiler.parsing.MXMLTokenTypes;
-import org.apache.flex.compiler.problems.ICompilerProblem;
-import org.apache.flex.compiler.problems.SyntaxProblem;
-
-/**
- * Encapsulation of a tag attribute in MXML
- */
-public class MXMLTagAttributeData extends SourceLocation implements
- IMXMLTagAttributeData
-{
- /**
- * Constructor.
- */
- MXMLTagAttributeData(MXMLToken nameToken, ListIterator<MXMLToken> tokenIterator, MXMLDialect mxmlDialect, IFileSpecification spec, Collection<ICompilerProblem> problems)
- {
- setStart(nameToken.getStart());
- setLine(nameToken.getLine());
- setColumn(nameToken.getColumn());
- setEnd(nameToken.getEnd());
-
- // Deal with name if it is of the form name.state
- MXMLStateSplitter splitState = new MXMLStateSplitter(nameToken, mxmlDialect, problems, spec);
- attributeName = splitState.baseName;
- if (splitState.stateName != null)
- {
- stateName = splitState.stateName;
- stateStart = nameToken.getStart() + splitState.stateNameOffset;
- }
-
- MXMLToken token = null;
-
- // Look for "=" token
- if (tokenIterator.hasNext())
- {
- token = tokenIterator.next();
-
- if (token.getType() != MXMLTokenTypes.TOKEN_EQUALS)
- {
- problems.add(new SyntaxProblem(token));
- // need to restore the token position in the error
- // case to handle error recovery otherwise the any
- // trees after this won't be created
- tokenIterator.previous();
- return;
- }
-
- valueStart = token.getEnd() + 1; //set the attributes start to right after the equals until we have a value
- valueLine = token.getLine();
- valueColumn = token.getColumn();
- }
-
- // Look for value token
- ArrayList<IMXMLTagAttributeValue> values = new ArrayList<IMXMLTagAttributeValue>(3);
- while (tokenIterator.hasNext())
- {
- token = tokenIterator.next();
- if (token.getType() == MXMLTokenTypes.TOKEN_DATABINDING_START)
- {
- values.add(new MXMLDatabindingValue(token, tokenIterator, this));
- }
- else if (token.getType() == MXMLTokenTypes.TOKEN_STRING)
- {
- values.add(new MXMLTextValue(token, this));
- }
- else if (token.isEntity())
- {
- values.add(new MXMLEntityValue(token, this));
- }
- else
- {
- if (!MXMLToken.isTagEnd(token.getType()) && token.getType() != MXMLTokenTypes.TOKEN_NAME)
- {
- // if we error out early, push back token - it may be start of next tag
- // this is "pre-falcon" repair that was lost
- tokenIterator.previous();
- problems.add(new SyntaxProblem(token));
- }
- else
- {
- tokenIterator.previous();
- }
- break;
- }
- }
-
- this.values = values.toArray(new MXMLTagAttributeValue[0]);
-
- if (this.values.length > 0)
- {
- //set the start value
- IMXMLTagAttributeValue value = this.values[0];
- valueStart = value.getAbsoluteStart();
- valueLine = value.getLine();
- valueColumn = value.getColumn();
- final int valueEnd = getValueEnd();
- setEnd(valueEnd + 1);
- }
- }
-
- /**
- * The MXML tag that contains this attribute
- */
- protected IMXMLTagData parent;
-
- /**
- * The name of this attribute.
- */
- protected String attributeName;
-
- /**
- * The offset at which the attribute value starts
- */
- protected int valueStart;
-
- /**
- * The line on which the attribute value starts
- */
- protected int valueLine;
-
- /**
- * The column at which the attribute value starts
- */
- protected int valueColumn;
-
- /**
- * Array of values inside this attribute data.
- */
- private IMXMLTagAttributeValue[] values = new IMXMLTagAttributeValue[0];
-
- /**
- * The name of this state, if it exists
- */
- protected String stateName;
-
- /**
- * The offset at which the optional state starts
- */
- protected int stateStart;
-
- /**
- * The URI specified by this attribute's prefix.
- */
- protected String uri;
-
- //
- // Object overrides.
- //
-
- // For debugging only. This format is nice in the Eclipse debugger.
- @Override
- public String toString()
- {
- StringBuilder sb = new StringBuilder();
- buildAttributeString(false);
- return sb.toString();
- }
-
- /**
- * For unit tests only.
- *
- * @return name value and offsets in string form
- */
- public String buildAttributeString(boolean skipSrcPath)
- {
- StringBuilder sb = new StringBuilder();
- sb.append(getName());
- sb.append('=');
- sb.append('"');
- sb.append(getRawValue());
- sb.append('"');
-
- sb.append(' ');
-
- // Display line, column, start, and end as "17:5 160-188".
- if (skipSrcPath)
- sb.append(getOffsetsString());
- else
- sb.append(super.toString());
- return sb.toString();
- }
-
- //
- // Other methods
- //
-
- @Override
- public IMXMLTagData getParent()
- {
- return parent;
- }
-
- /**
- * Sets this attribute's tag.
- *
- * @param parent MXML tag containing this attribute
- */
- public void setParent(IMXMLTagData parent)
- {
- this.parent = parent;
- setSourcePath(parent.getSourcePath());
- }
-
- /**
- * Adjust all associated offsets by the adjustment amount
- *
- * @param offsetAdjustment amount to add to offsets
- */
- public void adjustOffsets(int offsetAdjustment)
- {
- if (attributeName != null)
- {
- setStart(getAbsoluteStart() + offsetAdjustment);
- setEnd(getAbsoluteEnd() + offsetAdjustment);
- }
-
- if (hasValue())
- {
- valueStart += offsetAdjustment;
- for (int i = 0; i < values.length; i++)
- {
- ((MXMLTagAttributeValue)values[i]).setStart(values[i].getAbsoluteStart() + offsetAdjustment);
- ((MXMLTagAttributeValue)values[i]).setEnd(values[i].getAbsoluteEnd() + offsetAdjustment);
- }
- }
-
- if (stateName != null)
- stateStart += offsetAdjustment;
- }
-
- @Override
- public String getName()
- {
- return attributeName;
- }
-
- @Override
- public String getStateName()
- {
- return stateName != null ? stateName : "";
- }
-
- /**
- * Checks whether this attribute is associated with a state.
- *
- * @return True if a state association exists.
- */
- public boolean hasState()
- {
- return stateName != null;
- }
-
- @Override
- public boolean hasValue()
- {
- return values.length > 0;
- }
-
- @Override
- public IMXMLTagAttributeValue[] getValues()
- {
- return values;
- }
-
- /**
- * Get the attribute value as a String (with quotes)
- *
- * @return attribute value (with quotes)
- */
- public String getValueWithQuotes()
- {
- StringBuilder value = new StringBuilder();
-
- final int size = values.length;
- IMXMLTagAttributeValue lastData = null;
- for (int i = 0; i < size; i++)
- {
- IMXMLTagAttributeValue data = values[i];
- if (lastData != null)
- {
- for (int s = 0; s < data.getAbsoluteStart() - lastData.getAbsoluteEnd(); i++)
- {
- value.append(" ");
- }
- }
- value.append(data.getContent());
- }
-
- return value.toString();
- }
-
- @Override
- public String getRawValue()
- {
- String value = getValueWithQuotes();
-
- if (value != null && value.length() > 0)
- {
- // length can be one in case of invalid data and then the substring() call fails
- // so, handle it here
- if (value.charAt(0) == value.charAt(value.length() - 1) && value.length() != 1)
- value = value.substring(1, value.length() - 1);
- else
- value = value.substring(1);
- }
-
- return value;
- }
-
- @Override
- public ISourceFragment[] getValueFragments(Collection<ICompilerProblem> problems)
- {
- String value = getRawValue();
- ISourceLocation location = getValueLocation();
- MXMLDialect mxmlDialect = getMXMLDialect();
-
- return EntityProcessor.parse(value, location, mxmlDialect, problems);
- }
-
- /**
- * Returns the value of the raw token (without quotes) only if only one
- * value exists and it is a string value New clients should take into
- * account that multiple values exist inside of an attribute value
- *
- * @return a value token, or null
- */
- // TODO Rename to getValueToken()
- public IMXMLToken getRawValueToken()
- {
- if (hasState() && values.length == 1 && values[0] instanceof IMXMLTextValue)
- {
- String value = getRawValue();
- if (value != null)
- {
- return new MXMLToken(MXMLTokenTypes.TOKEN_STRING, getValueStart() + 1, getValueStart() + 1 + value.length(), -1, -1, value);
- }
- }
- return null;
- }
-
- public IFileSpecification getSource()
- {
- return getParent().getSource();
- }
-
- /**
- * Get this unit's line number.
- *
- * @return end offset
- */
- public final int getNameLine()
- {
- return getLine();
- }
-
- /**
- * Get this unit's column number.
- *
- * @return end offset
- */
- public final int getNameColumn()
- {
- return getColumn();
- }
-
- public int getNameStart()
- {
- return getAbsoluteStart();
- }
-
- /**
- * Get this attribute's name's end offset
- *
- * @return name end offset
- */
- public int getNameEnd()
- {
- return getAbsoluteStart() + attributeName.length();
- }
-
- @Override
- public int getValueStart()
- {
- return hasValue() ? valueStart + 1 : 0;
- }
-
- @Override
- public int getValueEnd()
- {
- if (hasValue())
- {
- String lastContent = values[values.length - 1].getContent();
-
- if (lastContent.charAt(0) == lastContent.charAt(lastContent.length() - 1))
- return getValueStart() + lastContent.length() - 2;
-
- return getValueStart() + lastContent.length();
- }
-
- // If there is no valid "end", then we must return -1. Callers depend on this.
- // See MXMLTagData.findArttributeContainingOffset for an example
- return -1;
- }
-
- @Override
- public int getValueLine()
- {
- return hasValue() ? valueLine : 0;
- }
-
- @Override
- public int getValueColumn()
- {
- return hasValue() ? valueColumn + 1 : 0;
- }
-
- @Override
- public SourceLocation getValueLocation()
- {
- return new SourceLocation(getSourcePath(), getValueStart(), getValueEnd(), getValueLine(), getValueColumn());
- }
-
- /**
- * Get this attribute's state start offset if a state token is present other
- * wise zero.
- *
- * @return state start offset or zero
- */
- public int getStateStart()
- {
- return stateName != null ? stateStart : 0;
- }
-
- /**
- * Get this attribute's state tokens end offset if a state token is present
- * other wise zero.
- *
- * @return state start offset or zero
- */
- public int getStateEnd()
- {
- return stateName != null ? stateStart + stateName.length() : 0;
- }
-
- /**
- * Does this value have a closing quote character?
- *
- * @return true if this value has a closing quote character
- */
- protected boolean valueIsWellFormed()
- {
- // If there is a value, it came from a string token. We know (from the
- // RawTagTokenizer) that this means it starts with a quote character. If
- // it ends with the same quote character, it's well formed.
- if (hasValue())
- {
- String lastContent = values[values.length - 1].getContent();
- return (lastContent.charAt(0) == lastContent.charAt(lastContent.length() - 1));
- }
-
- return false;
- }
-
- /**
- * Returns the {@link PrefixMap} that represents all prefix->namespace
- * mappings are in play on this tag. For example, if a parent tag defines
- * <code>xmlns:m="falcon"</code> and this tag defines
- * <code>xmlns:m="eagle"</code> then in this prefix map, m will equal
- * "eagle"
- *
- * @return a {@link PrefixMap} or null
- */
- public PrefixMap getCompositePrefixMap()
- {
- return parent.getCompositePrefixMap();
- }
-
- /**
- * Does the offset fall inside the bounds of the attribute name?
- *
- * @param offset test offset
- * @return true if the offset falls within the attribute name
- */
- public boolean isInsideName(int offset)
- {
- if (attributeName != null)
- return MXMLData.contains(getNameStart(), getNameEnd(), offset);
-
- return false;
- }
-
- public boolean isInsideStateName(int offset)
- {
- if (stateName != null)
- return MXMLData.contains(getStateStart(), getStateEnd(), offset);
-
- return false;
- }
-
- /**
- * Does the offset fall inside the bounds of the attribute value?
- *
- * @param offset test offset
- * @return true if the offset falls within the attribute value
- */
- public boolean isInsideValue(int offset)
- {
- if (hasValue())
- return MXMLData.contains(getValueStart() - 1, getValueEnd(), offset);
-
- return false;
- }
-
- @Override
- public String getPrefix()
- {
- String name = getName();
- int i = name.indexOf(':');
- return i != -1 ? name.substring(0, i) : null;
- }
-
- @Override
- public String getShortName()
- {
- String name = getName();
- int i = name.indexOf(':');
- return i != -1 ? name.substring(i + 1) : name;
- }
-
- @Override
- public XMLName getXMLName()
- {
- return new XMLName(getURI(), getShortName());
- }
-
- @Override
- public String getURI()
- {
- if (uri == null)
- {
- //walk up our chain to find the correct uri for our namespace. first one wins
- String prefix = getPrefix();
- if (prefix == null)
- return null;
-
- IMXMLTagData lookingAt = parent;
-
- // For attributes with prefix, parent's parent can be null if
- // parent is the root tag
- while (lookingAt != null && lookingAt.getParent() != null)
- {
- PrefixMap depth = lookingAt.getParent().getPrefixMapForData(lookingAt);
- if (depth != null && depth.containsPrefix(prefix))
- {
- uri = depth.getNamespaceForPrefix(prefix);
- break;
- }
-
- lookingAt = lookingAt.getParentTag();
- }
- }
-
- return uri;
- }
-
- void invalidateURI()
- {
- uri = null;
- }
-
- @Override
- public MXMLDialect getMXMLDialect()
- {
- return getParent().getParent().getMXMLDialect();
- }
-
- @Override
- public boolean isSpecialAttribute(String name)
- {
- String languageURI = getMXMLDialect().getLanguageNamespace();
-
- return getName().equals(name) && (getPrefix() == null || getURI() == languageURI);
- }
-
- /**
- * Verifies that this attrobite has its source location information set.
- * <p>
- * This is used only in asserts.
- */
- public boolean verify()
- {
- // Verify the source location.
- assert getSourcePath() != null : "Attribute has null source path: " + toString();
- assert getStart() != UNKNOWN : "Attribute has unknown start: " + toString();
- assert getEnd() != UNKNOWN : "Attribute has unknown end: " + toString();
- assert getLine() != UNKNOWN : "Attribute has unknown line: " + toString();
- assert getColumn() != UNKNOWN : "Attribute has unknown column: " + toString();
-
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLTagAttributeValue.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLTagAttributeValue.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLTagAttributeValue.java
deleted file mode 100644
index d095df6..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLTagAttributeValue.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import org.apache.flex.compiler.common.SourceLocation;
-
-public abstract class MXMLTagAttributeValue extends SourceLocation implements
- IMXMLTagAttributeValue
-{
- /**
- * Constructor.
- */
- public MXMLTagAttributeValue(IMXMLTagAttributeData parent)
- {
- this.parent = parent;
-
- if (parent != null)
- setSourcePath(parent.getSourcePath());
- }
-
- /**
- * The MXML attribute that contains this unit
- */
- private IMXMLTagAttributeData parent;
-
- //
- // Other methods
- //
-
- public IMXMLTagAttributeData getContainingAttribute()
- {
- return parent;
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/mxml/MXMLTagBlobData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/MXMLTagBlobData.java b/compiler/src/org/apache/flex/compiler/mxml/MXMLTagBlobData.java
deleted file mode 100644
index 06cf0bd..0000000
--- a/compiler/src/org/apache/flex/compiler/mxml/MXMLTagBlobData.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.mxml;
-
-import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
-
-/**
- * An MXML blob is a large chunk of MXML data that was passed over during
- * tokenization. A blob, for example could be the contents of an fx:Private tag.
- */
-public class MXMLTagBlobData extends MXMLUnitData implements IMXMLTagBlobData
-{
- /**
- * Constructor.
- *
- * @param token
- */
- MXMLTagBlobData(MXMLToken token)
- {
- String text = token.getText();
- int length = text.length();
- int pos = 1;
- while (pos < length)
- {
- if (Character.isWhitespace(text.charAt(pos)))
- break;
- pos++;
- }
- name = text.substring(1, pos - 1);
-
- setStart(token.getStart());
- setEnd(token.getEnd());
- setLine(token.getLine());
- setColumn(token.getColumn());
- }
-
- private String name;
-
- //
- // IMXMLTagBlobData implementations
- //
-
- @Override
- public String getName()
- {
- return name;
- }
-}
[4/4] git commit: [flex-falcon] - Moved MXMLData-related classes into
internal package
Posted by go...@apache.org.
Moved MXMLData-related classes into internal package
Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/bec3ba00
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/bec3ba00
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/bec3ba00
Branch: refs/heads/develop
Commit: bec3ba0024522bcd14b27960fab667b648deef9b
Parents: 1c7ddc2
Author: Gordon Smith <go...@adobe.com>
Authored: Mon Apr 15 20:01:28 2013 -0700
Committer: Gordon Smith <go...@adobe.com>
Committed: Mon Apr 15 20:01:28 2013 -0700
----------------------------------------------------------------------
.../compiler/internal/test/FlexJSTestBase.java | 2 +-
.../flex/compiler/internal/test/MXMLTestBase.java | 2 +-
.../internal/tree/mxml/MXMLNodeBaseTests.java | 2 +-
.../flex/compiler/common/PrefixedXMLName.java | 2 +-
.../apache/flex/compiler/config/Configuration.java | 2 +-
.../compiler/internal/caches/MXMLDataCache.java | 2 +-
.../flex/compiler/internal/mxml/MXMLData.java | 980 +++++++++++++
.../compiler/internal/mxml/MXMLDataManager.java | 1 -
.../internal/mxml/MXMLDatabindingData.java | 58 +
.../internal/mxml/MXMLDatabindingValue.java | 113 ++
.../compiler/internal/mxml/MXMLEntityData.java | 80 +
.../compiler/internal/mxml/MXMLEntityValue.java | 144 ++
.../internal/mxml/MXMLInstructionData.java | 97 ++
.../internal/mxml/MXMLNamespaceAttributeData.java | 64 +
.../internal/mxml/MXMLNamespaceMapping.java | 76 +
.../compiler/internal/mxml/MXMLStateSplitter.java | 86 ++
.../internal/mxml/MXMLTagAttributeData.java | 637 ++++++++
.../internal/mxml/MXMLTagAttributeValue.java | 53 +
.../compiler/internal/mxml/MXMLTagBlobData.java | 66 +
.../flex/compiler/internal/mxml/MXMLTagData.java | 1135 +++++++++++++++
.../flex/compiler/internal/mxml/MXMLTextData.java | 404 +++++
.../flex/compiler/internal/mxml/MXMLTextValue.java | 82 ++
.../flex/compiler/internal/mxml/MXMLUnitData.java | 366 +++++
.../compiler/internal/mxml/StateDefinition.java | 93 ++
.../internal/mxml/StateDefinitionBase.java | 75 +
.../internal/mxml/StateGroupDefinition.java | 84 ++
.../internal/parsing/mxml/MXMLTagDataDepth.java | 2 +-
.../compiler/internal/projects/FlexProject.java | 2 +-
.../tree/mxml/MXMLClassDefinitionNode.java | 4 +-
.../compiler/internal/tree/mxml/MXMLStateNode.java | 2 +-
.../org/apache/flex/compiler/mxml/IMXMLData.java | 1 +
.../org/apache/flex/compiler/mxml/MXMLData.java | 977 -------------
.../flex/compiler/mxml/MXMLDatabindingData.java | 56 -
.../flex/compiler/mxml/MXMLDatabindingValue.java | 111 --
.../apache/flex/compiler/mxml/MXMLEntityData.java | 79 -
.../apache/flex/compiler/mxml/MXMLEntityValue.java | 142 --
.../flex/compiler/mxml/MXMLInstructionData.java | 96 --
.../compiler/mxml/MXMLNamespaceAttributeData.java | 64 -
.../flex/compiler/mxml/MXMLNamespaceMapping.java | 74 -
.../flex/compiler/mxml/MXMLStateSplitter.java | 87 --
.../flex/compiler/mxml/MXMLTagAttributeData.java | 635 --------
.../flex/compiler/mxml/MXMLTagAttributeValue.java | 51 -
.../apache/flex/compiler/mxml/MXMLTagBlobData.java | 65 -
.../org/apache/flex/compiler/mxml/MXMLTagData.java | 1130 --------------
.../apache/flex/compiler/mxml/MXMLTextData.java | 405 -----
.../apache/flex/compiler/mxml/MXMLTextValue.java | 80 -
.../apache/flex/compiler/mxml/MXMLUnitData.java | 364 -----
.../apache/flex/compiler/mxml/StateDefinition.java | 91 --
.../flex/compiler/mxml/StateDefinitionBase.java | 74 -
.../flex/compiler/mxml/StateGroupDefinition.java | 82 --
50 files changed, 4705 insertions(+), 4675 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler.jx.tests/src/org/apache/flex/compiler/internal/test/FlexJSTestBase.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/test/FlexJSTestBase.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/test/FlexJSTestBase.java
index 7b9a421..ce25e18 100644
--- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/test/FlexJSTestBase.java
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/test/FlexJSTestBase.java
@@ -5,9 +5,9 @@ import java.util.List;
import org.apache.flex.compiler.driver.IBackend;
import org.apache.flex.compiler.internal.driver.mxml.flexjs.MXMLFlexJSBackend;
+import org.apache.flex.compiler.internal.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.internal.projects.FlexJSProject;
import org.apache.flex.compiler.mxml.IMXMLNamespaceMapping;
-import org.apache.flex.compiler.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.tree.mxml.IMXMLFileNode;
import org.apache.flex.compiler.tree.mxml.IMXMLNode;
import org.apache.flex.utils.FilenameNormalization;
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler.jx.tests/src/org/apache/flex/compiler/internal/test/MXMLTestBase.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/test/MXMLTestBase.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/test/MXMLTestBase.java
index d0f793a..c8a1041 100644
--- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/test/MXMLTestBase.java
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/test/MXMLTestBase.java
@@ -5,8 +5,8 @@ import java.util.List;
import org.apache.flex.compiler.driver.IBackend;
import org.apache.flex.compiler.internal.driver.mxml.MXMLBackend;
+import org.apache.flex.compiler.internal.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.mxml.IMXMLNamespaceMapping;
-import org.apache.flex.compiler.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.tree.mxml.IMXMLFileNode;
import org.apache.flex.compiler.tree.mxml.IMXMLNode;
import org.apache.flex.compiler.tree.mxml.IMXMLPropertySpecifierNode;
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler.tests/unit-tests/org/apache/flex/compiler/internal/tree/mxml/MXMLNodeBaseTests.java
----------------------------------------------------------------------
diff --git a/compiler.tests/unit-tests/org/apache/flex/compiler/internal/tree/mxml/MXMLNodeBaseTests.java b/compiler.tests/unit-tests/org/apache/flex/compiler/internal/tree/mxml/MXMLNodeBaseTests.java
index 684c6bc..3a82b9c 100644
--- a/compiler.tests/unit-tests/org/apache/flex/compiler/internal/tree/mxml/MXMLNodeBaseTests.java
+++ b/compiler.tests/unit-tests/org/apache/flex/compiler/internal/tree/mxml/MXMLNodeBaseTests.java
@@ -29,12 +29,12 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import org.apache.flex.compiler.internal.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.internal.projects.FlexProject;
import org.apache.flex.compiler.internal.projects.FlexProjectConfigurator;
import org.apache.flex.compiler.internal.units.SourceCompilationUnitFactory;
import org.apache.flex.compiler.internal.workspaces.Workspace;
import org.apache.flex.compiler.mxml.IMXMLNamespaceMapping;
-import org.apache.flex.compiler.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.tree.as.IASNode;
import org.apache.flex.compiler.tree.mxml.IMXMLFileNode;
import org.apache.flex.compiler.units.ICompilationUnit;
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/common/PrefixedXMLName.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/common/PrefixedXMLName.java b/compiler/src/org/apache/flex/compiler/common/PrefixedXMLName.java
index bce90e9..afcd6f9 100644
--- a/compiler/src/org/apache/flex/compiler/common/PrefixedXMLName.java
+++ b/compiler/src/org/apache/flex/compiler/common/PrefixedXMLName.java
@@ -20,7 +20,7 @@
package org.apache.flex.compiler.common;
import org.apache.flex.compiler.constants.IMXMLCoreConstants;
-import org.apache.flex.compiler.mxml.MXMLData;
+import org.apache.flex.compiler.internal.mxml.MXMLData;
/**
* A subclass of XMLName used by clients that need to manipulate the actual
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/config/Configuration.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/config/Configuration.java b/compiler/src/org/apache/flex/compiler/config/Configuration.java
index 362fbd7..6cbb8a7 100644
--- a/compiler/src/org/apache/flex/compiler/config/Configuration.java
+++ b/compiler/src/org/apache/flex/compiler/config/Configuration.java
@@ -79,8 +79,8 @@ import org.apache.flex.compiler.internal.config.annotations.InfiniteArguments;
import org.apache.flex.compiler.internal.config.annotations.Mapping;
import org.apache.flex.compiler.internal.config.annotations.SoftPrerequisites;
import org.apache.flex.compiler.internal.config.localization.LocalizationManager;
+import org.apache.flex.compiler.internal.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.mxml.IMXMLTypeConstants;
-import org.apache.flex.compiler.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.problems.ConfigurationProblem;
import org.apache.flex.compiler.problems.DeprecatedConfigurationOptionProblem;
import org.apache.flex.compiler.problems.FlexOnlyConfigurationOptionNotSupported;
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/caches/MXMLDataCache.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/caches/MXMLDataCache.java b/compiler/src/org/apache/flex/compiler/internal/caches/MXMLDataCache.java
index 51ec3f0..7f06a2d 100644
--- a/compiler/src/org/apache/flex/compiler/internal/caches/MXMLDataCache.java
+++ b/compiler/src/org/apache/flex/compiler/internal/caches/MXMLDataCache.java
@@ -26,9 +26,9 @@ import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.internal.mxml.MXMLData;
import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
import org.apache.flex.compiler.internal.parsing.mxml.MXMLTokenizer;
-import org.apache.flex.compiler.mxml.MXMLData;
/**
* Concurrent cache for parsed MXML models. The cache is a list of key-value pairs.
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLData.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLData.java
new file mode 100644
index 0000000..9c4c093
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLData.java
@@ -0,0 +1,980 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+
+import org.apache.flex.compiler.common.MutablePrefixMap;
+import org.apache.flex.compiler.common.PrefixMap;
+import org.apache.flex.compiler.filespecs.FileSpecification;
+import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.internal.parsing.mxml.BalancingMXMLProcessor;
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLTokenizer;
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLUnitDataIterator;
+import org.apache.flex.compiler.mxml.IMXMLData;
+import org.apache.flex.compiler.mxml.IMXMLTagAttributeData;
+import org.apache.flex.compiler.mxml.IMXMLTagData;
+import org.apache.flex.compiler.mxml.IMXMLUnitData;
+import org.apache.flex.compiler.parsing.MXMLTokenTypes;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.problems.SyntaxProblem;
+import org.apache.flex.utils.FastStack;
+import org.apache.flex.utils.FastStack.IFastStackDecorator;
+
+/**
+ * Encapsulation of an MXML file, with individual units for each open tag, close
+ * tag, and block of text.
+ */
+public class MXMLData implements IMXMLData
+{
+
+ private final class TokenizerPayload
+ {
+ private List<MXMLToken> tokens;
+
+ private PrefixMap prefixMap;
+
+ public TokenizerPayload(List<MXMLToken> tokens, PrefixMap prefixMap)
+ {
+ this.tokens = tokens;
+ this.prefixMap = prefixMap;
+ }
+
+ public List<MXMLToken> getMXMLTokens()
+ {
+ return tokens;
+ }
+
+ public PrefixMap getPrefixMap()
+ {
+ return prefixMap;
+ }
+ }
+
+ /**
+ * A cursor represents the offset into the document and the index of the
+ * MXML unit that contains that offset
+ */
+ public class Cursor
+ {
+ /**
+ * Offset into the document
+ */
+ private int offset;
+ /**
+ * Index of the unit that contains that offset
+ */
+ private int unitIndex;
+
+ /**
+ * Constructor (points to beginning of the MXMLData)
+ */
+ public Cursor()
+ {
+ reset();
+ }
+
+ /**
+ * Reset cursor to the beginning of the MXMLData
+ */
+ public void reset()
+ {
+ offset = 0;
+ unitIndex = 0;
+ }
+
+ /**
+ * Set the cursor to a particular offset/unit
+ *
+ * @param offset offset into the document
+ * @param unitIndex index of the unit containing that offset
+ */
+ public void setCursor(int offset, int unitIndex)
+ {
+ this.offset = offset;
+ this.unitIndex = unitIndex;
+ }
+
+ /**
+ * Get the offset the cursor is pointing to
+ *
+ * @return current document offset
+ */
+ public int getOffset()
+ {
+ return offset;
+ }
+
+ /**
+ * Get the index of the unit the cursor is pointing to
+ *
+ * @return current unit index
+ */
+ public int getUnitIndex()
+ {
+ return unitIndex;
+ }
+ }
+
+ private String path = null;
+
+ /**
+ * Individual units for each open tag, close tag, and block of text
+ */
+ private IMXMLUnitData[] units;
+
+ /**
+ * Flag indicating that the tokens underlying this structure were fixed
+ */
+ private boolean wasRepaired;
+
+ private boolean shouldRepair = true;
+
+ /**
+ * This maps {@link IMXMLTagData} objects to their explicit
+ * {@link PrefixMap} if it exist
+ */
+ private HashMap<IMXMLTagData, PrefixMap> nsMap;
+
+ /**
+ * The cursor holds the result of last offset lookup into the MXMLData (see
+ * findNearestUnit, below). When an edit happens that causes the code
+ * coloring engine to recompute everything from the edit position to the end
+ * of the document, it will request MXMLOffsetInformations in order. Having
+ * the cursor speeds this up tremendously.
+ */
+ private Cursor cursor;
+
+ /**
+ * The dialect of MXML being used.
+ */
+ private MXMLDialect mxmlDialect;
+
+ private Collection<ICompilerProblem> problems = new ArrayList<ICompilerProblem>(2);
+
+ /**
+ * Tells us if we are currently processing full MXML, or a fragment
+ */
+ private boolean fullContent = true;
+
+ /**
+ * Constructor
+ *
+ * @param tokens MXML tokens to build the MXMLData object from
+ * @param map the {@link PrefixMap} for the document, containing the
+ * namespace/prefix mappings
+ */
+ public MXMLData(List<MXMLToken> tokens, PrefixMap map, IFileSpecification fileSpec)
+ {
+ path = fileSpec.getPath();
+ init(tokens, map);
+ }
+
+ public MXMLData(List<MXMLToken> tokens, PrefixMap map, IFileSpecification fileSpec, boolean shouldRepair)
+ {
+ path = fileSpec.getPath();
+ this.shouldRepair = false;
+ init(tokens, map);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param mxmlText input build our {@link MXMLData} from
+ */
+ public MXMLData(int startOffset, Reader mxmlText, IFileSpecification fileSpec)
+ {
+ TokenizerPayload payload = getTokens(startOffset, mxmlText);
+ path = fileSpec.getPath();
+ init(payload.getMXMLTokens(), payload.getPrefixMap());
+ }
+
+ /**
+ * Constructor
+ *
+ * @param mxmlText input build our {@link MXMLData} from
+ */
+ public MXMLData(int startOffset, Reader mxmlText, String path, boolean fullContent)
+ {
+ this.fullContent = fullContent;
+ TokenizerPayload payload = getTokens(startOffset, mxmlText);
+ this.path = path;
+ init(payload.getMXMLTokens(), payload.getPrefixMap());
+ }
+
+ public MXMLData(Reader mxmlText, IFileSpecification fileSpec)
+ {
+ this(0, mxmlText, fileSpec);
+ }
+
+ public MXMLData(Reader mxmlText, String path)
+ {
+ // Some clients of MXML data pass in a null IPath for the source path.
+ // Specifically this seems to happen in the code that builds a new
+ // mxml document from a template.
+ this(0, mxmlText, path != null ? path : null, true);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param specification input build our {@link MXMLData} from
+ */
+ public MXMLData(IFileSpecification specification)
+ {
+ TokenizerPayload payload;
+ try
+ {
+ path = specification.getPath();
+ payload = getTokens(specification.createReader());
+ init(payload.getMXMLTokens(), payload.getPrefixMap());
+ }
+ catch (FileNotFoundException e)
+ {
+ //do nothing
+ }
+ }
+
+ private void init(List<MXMLToken> tokens, PrefixMap map)
+ {
+ mxmlDialect = MXMLDialect.getMXMLDialect(map);
+ initializeFromTokens(tokens);
+ }
+
+ /**
+ * Update the version of the mxml data
+ *
+ * @param map the prefix map
+ */
+ public void updateMXMLVersion(PrefixMap map)
+ {
+ mxmlDialect = MXMLDialect.getMXMLDialect(map);
+ }
+
+ /**
+ * Get the namespaces defined on the root tag
+ *
+ * @param reader The reader which would provide the root tag information
+ * @return {@link PrefixMap} for the root tag
+ * @throws IOException error
+ */
+ public static PrefixMap getRootNamespaces(Reader reader) throws IOException
+ {
+ MXMLTokenizer tokenizer = new MXMLTokenizer();
+ try
+ {
+ tokenizer.setReader(reader);
+ return tokenizer.getRootTagPrefixMap().clone();
+ }
+ finally
+ {
+ tokenizer.close();
+ }
+ }
+
+ protected TokenizerPayload getTokens(Reader reader)
+ {
+ return getTokens(0, reader);
+ }
+
+ protected TokenizerPayload getTokens(int startOffset, Reader reader)
+ {
+ List<MXMLToken> tokens = null;
+ MXMLTokenizer tokenizer = new MXMLTokenizer(startOffset);
+ try
+ {
+ tokenizer.setIsRepairing(true);
+ tokens = tokenizer.parseTokens(reader);
+ wasRepaired = tokenizer.tokensWereRepaired();
+ return new TokenizerPayload(tokens, tokenizer.getPrefixMap());
+ }
+ finally
+ {
+ IOUtils.closeQuietly(tokenizer);
+ }
+ }
+
+ @Override
+ public MXMLDialect getMXMLDialect()
+ {
+ return mxmlDialect;
+ }
+
+ @Override
+ public PrefixMap getPrefixMapForData(IMXMLTagData data)
+ {
+ PrefixMap result = nsMap.get(data);
+ if (result != null)
+ return result;
+ if (data.isCloseTag())
+ {
+ IMXMLTagData openTagData = data.getParent().findTagOrSurroundingTagContainingOffset(data.getAbsoluteStart());
+ if (openTagData != null)
+ return nsMap.get(openTagData);
+ }
+ return null;
+ }
+
+ void removePrefixMappingForTag(IMXMLTagData data)
+ {
+ nsMap.remove(data);
+ }
+
+ void clearPrefixMappings()
+ {
+ nsMap.clear();
+ }
+
+ public void setPrefixMappings(HashMap<IMXMLTagData, PrefixMap> map)
+ {
+ if (nsMap != null)
+ nsMap.clear();
+ nsMap = map;
+ }
+
+ public Map<IMXMLTagData, PrefixMap> getTagToPrefixMap()
+ {
+ return nsMap;
+ }
+
+ /**
+ * Returns a collection of prefix->namespaces mappings found within this
+ * document. This map DOES NOT maintain order, and for more fine-grained
+ * information, the getPrefixMap call on individual {@link IMXMLTagData} and
+ * {@link IMXMLTagAttributeData} objects should be called
+ *
+ * @return a prefix map
+ */
+ public PrefixMap getDocumentPrefixMap()
+ {
+ MutablePrefixMap map = new MutablePrefixMap();
+ for (PrefixMap tagMap : nsMap.values())
+ {
+ assert tagMap != null;
+ map.addAll(tagMap);
+ }
+ return map.toImmutable();
+ }
+
+ /**
+ * Returns the PrefixMap for the root tag of this {@link MXMLData} object
+ *
+ * @return a {@link PrefixMap} or null
+ */
+ public PrefixMap getRootTagPrefixMap()
+ {
+ IMXMLTagData rootTag = getRootTag();
+ if (rootTag != null)
+ {
+ return nsMap.get(rootTag);
+ }
+ return null;
+ }
+
+ @Override
+ public Collection<ICompilerProblem> getProblems()
+ {
+ return problems;
+ }
+
+ public boolean hasProblems()
+ {
+ return problems.size() > 0;
+ }
+
+ /**
+ * Determines if this data was built from a source that was repaired
+ *
+ * @return true if the underlying source was repaired
+ */
+ public boolean isDataRepaired()
+ {
+ return wasRepaired;
+ }
+
+ public void setWasRepaired(boolean wasRepaired)
+ {
+ this.wasRepaired = wasRepaired;
+ }
+
+ @Override
+ public IFileSpecification getFileSpecification()
+ {
+ return new FileSpecification(path);
+ }
+
+ @Override
+ public String getPath()
+ {
+ return path;
+ }
+
+ /**
+ * API to change the path after MXMLData creation. An MXMLDocument makes an
+ * MXMLData before the actual location is known.
+ *
+ * @param path is the absolute path to the backing source file
+ */
+ public void setPath(String path)
+ {
+ this.path = path;
+ }
+
+ /**
+ * Common code from the two constructors
+ *
+ * @param tokens A list of MXML tokens.
+ */
+ protected void initializeFromTokens(List<MXMLToken> tokens)
+ {
+ cursor = new Cursor();
+ parse(this, tokens, mxmlDialect, problems);
+ cursor.reset();
+ }
+
+ /**
+ * Use the MXML tokens to build MXMLUnitData.
+ *
+ * @param data the {@link MXMLData} object
+ * @param tokens the list of tokens to build this data from
+ * @param dialect the {@link MXMLDialect} we are working against
+ * @param incremental true if this data is being built incrementally. All
+ * location updates will need to be done outside this element
+ */
+ private void parse(MXMLData data, List<MXMLToken> tokens, MXMLDialect dialect, Collection<ICompilerProblem> problems)
+ {
+ ArrayList<MXMLUnitData> units = new ArrayList<MXMLUnitData>(tokens.size() / 6);
+ nsMap = new HashMap<IMXMLTagData, PrefixMap>();
+ MXMLUnitData unit = null;
+ MXMLToken currentComment = null;
+ FastStack<Integer> depth = new FastStack<Integer>(tokens.size() / 8);
+ IFileSpecification spec = new FileSpecification(data.getPath() != null ? data.getPath() : "");
+ depth.setStackDecorator(new IFastStackDecorator<Integer>() {
+ @Override
+ public Integer decorate(Integer e)
+ {
+ if (e == null)
+ return -1;
+ return e;
+ }
+
+ });
+ int index = -1;
+ int balancingIndex = 0;
+ depth.push(index);
+ ListIterator<MXMLToken> tokenIterator = tokens.listIterator();
+ BalancingMXMLProcessor processor = new BalancingMXMLProcessor(getFileSpecification(), problems);
+ while (tokenIterator.hasNext())
+ {
+ MXMLToken token = tokenIterator.next();
+ switch (token.getType())
+ {
+ case MXMLTokenTypes.TOKEN_ASDOC_COMMENT:
+ currentComment = token;
+ //treat this like text.
+ unit = new MXMLTextData(token);
+ units.add(unit);
+ index++;
+ if (fullContent)
+ {
+ unit.setParentUnitDataIndex(depth.peek());
+ unit.setLocation(data, index);
+ }
+ break;
+ case MXMLTokenTypes.TOKEN_COMMENT:
+ case MXMLTokenTypes.TOKEN_CDATA:
+ case MXMLTokenTypes.TOKEN_WHITESPACE:
+ //treat this like text.
+ unit = new MXMLTextData(token);
+ units.add(unit);
+ index++;
+ if (fullContent)
+ {
+ unit.setParentUnitDataIndex(depth.peek());
+ unit.setLocation(data, index);
+ }
+ break;
+ case MXMLTokenTypes.TOKEN_OPEN_TAG_START:
+ unit = new MXMLTagData();
+ MutablePrefixMap map = ((MXMLTagData)unit).init(this, token, tokenIterator, dialect, spec, problems);
+ ((MXMLTagData)unit).setCommentToken(currentComment);
+ currentComment = null;
+ units.add(unit);
+ index++;
+ if (fullContent)
+ {
+ unit.setParentUnitDataIndex(depth.peek());
+ unit.setLocation(data, index);
+ if (!((MXMLTagData)unit).isEmptyTag())
+ processor.addOpenTag((MXMLTagData)unit, balancingIndex);
+ }
+ if (map != null)
+ nsMap.put((MXMLTagData)unit, map.toImmutable());
+ if (!((MXMLTagData)unit).isEmptyTag())
+ {
+ depth.push(index);
+ balancingIndex++;
+ }
+ break;
+ case MXMLTokenTypes.TOKEN_CLOSE_TAG_START:
+ unit = new MXMLTagData();
+ ((MXMLTagData)unit).init(this, token, tokenIterator, dialect, spec, problems);
+ ((MXMLTagData)unit).setCommentToken(currentComment);
+ if (!((MXMLTagData)unit).isEmptyTag())
+ {
+ depth.pop();
+ balancingIndex--;
+ }
+ index++;
+ if (fullContent)
+ {
+ unit.setLocation(data, index);
+ unit.setParentUnitDataIndex(depth.peek());
+ processor.addCloseTag((MXMLTagData)unit, balancingIndex);
+ }
+ currentComment = null;
+ units.add(unit);
+ break;
+ case MXMLTokenTypes.TOKEN_TEXT:
+ unit = new MXMLTextData(token);
+ units.add(unit);
+ index++;
+ if (fullContent)
+ {
+ unit.setParentUnitDataIndex(depth.peek());
+ unit.setLocation(data, index);
+ }
+ break;
+ case MXMLTokenTypes.TOKEN_MXML_BLOB:
+ unit = new MXMLTagBlobData(token);
+ units.add(unit);
+ index++;
+ if (fullContent)
+ {
+ unit.setParentUnitDataIndex(depth.peek());
+ unit.setLocation(data, index);
+ }
+ break;
+ case MXMLTokenTypes.TOKEN_DATABINDING_START:
+ unit = new MXMLDatabindingData(token, tokenIterator);
+ units.add(unit);
+ index++;
+ if (fullContent)
+ {
+ unit.setParentUnitDataIndex(depth.peek());
+ unit.setLocation(data, index);
+ }
+ break;
+ case MXMLTokenTypes.TOKEN_PROCESSING_INSTRUCTION:
+ unit = new MXMLInstructionData(token);
+ units.add(unit);
+ index++;
+ if (fullContent)
+ {
+ unit.setParentUnitDataIndex(depth.peek());
+ unit.setLocation(data, index);
+ }
+ break;
+ default:
+ if (token.isEntity())
+ {
+ unit = new MXMLEntityData(token);
+ units.add(unit);
+ index++;
+ if (fullContent)
+ {
+ unit.setParentUnitDataIndex(depth.peek());
+ unit.setLocation(data, index);
+ }
+ break;
+ }
+ else
+ {
+ problems.add(new SyntaxProblem(token));
+ break;
+ }
+ }
+ }
+ this.units = units.toArray(new IMXMLUnitData[0]);
+ if (fullContent && shouldRepair)
+ {
+ this.units = processor.balance(this.units, this, nsMap);
+ if (processor.wasRepaired())
+ { //repaired, so let's rebuild our prefix maps and tag depths
+ refreshPositionData();
+ }
+ }
+ }
+
+ /**
+ * Used to rebuild the structures inside of the MXMLData, refreshing prefix
+ * maps, depth and position data. Should only be used after calls that
+ * rebuild the internal structure are called
+ */
+ public void refreshPositionData()
+ {
+ FastStack<Integer> depth = new FastStack<Integer>(units.length / 2);
+ depth.setStackDecorator(new IFastStackDecorator<Integer>() {
+ @Override
+ public Integer decorate(Integer e)
+ {
+ if (e == null)
+ return -1;
+ return e;
+ }
+
+ });
+ depth.clear();
+ depth.push(-1);
+ for (int i = 0; i < units.length; i++)
+ {
+ if (units[i] instanceof IMXMLTagData)
+ {
+ IMXMLTagData currentTag = (IMXMLTagData)units[i];
+ if (currentTag.isCloseTag())
+ {
+ if (!currentTag.isEmptyTag())
+ depth.pop();
+ }
+ ((MXMLTagData)currentTag).setParentUnitDataIndex(depth.peek());
+ ((MXMLTagData)currentTag).setLocation(this, i);
+ if (currentTag.isOpenTag())
+ {
+ if (!currentTag.isEmptyTag())
+ {
+ depth.push(i);
+ }
+ }
+ }
+ else
+ {
+ ((MXMLUnitData)units[i]).setParentUnitDataIndex(depth.peek());
+ ((MXMLUnitData)units[i]).setLocation(this, i);
+ }
+ }
+ }
+
+ @Override
+ public IMXMLUnitData[] getUnits()
+ {
+ return units;
+ }
+
+ public Iterator<IMXMLUnitData> getUnitIterator()
+ {
+ return new MXMLUnitDataIterator(units);
+ }
+
+ /**
+ * Replace the list of units in this MXMLData.
+ *
+ * @param units units to add
+ */
+ public void setUnits(IMXMLUnitData[] units)
+ {
+ this.units = units;
+ }
+
+ @Override
+ public IMXMLUnitData getUnit(int i)
+ {
+ if (i < 0 || i >= units.length)
+ return null;
+ return units[i];
+ }
+
+ @Override
+ public int getNumUnits()
+ {
+ return units.length;
+ }
+
+ /**
+ * If the offset is contained within an MXML unit, get that unit. If it's
+ * not, then get the first unit that follows the offset.
+ *
+ * @param offset test offset
+ * @return unit that contains (or immediately follows) the offset A few
+ * subtleties: In Falcon we have endeavored to preserve the existing
+ * definition of "nearest", so that for a given MXML file, falcon will find
+ * the same "nearest" unit.
+ */
+
+ protected IMXMLUnitData findNearestUnit(int offset)
+ {
+
+ // Use the cursor as a fast search hint. But only if the cursor is at or before the
+ // are of interest.
+ // TODO: do we care that this is not thread safe?
+ int startOffset = 0;
+ if (cursor.getOffset() <= offset)
+ startOffset = cursor.getUnitIndex();
+
+ // Sanity check
+ if (startOffset < 0 || startOffset >= units.length)
+ startOffset = 0;
+
+ // Now iterate though the units and find the first one that is acceptable
+ IMXMLUnitData ret = null;
+ for (int i = startOffset; (i < units.length) && (ret == null); i++)
+ {
+ IMXMLUnitData unit = units[i];
+
+ // unit is a match if it "contains" the offset.
+ // We are using a somewhat bizarre form of "contains" here, in that we are
+ // using getStart() and getConentEnd(). This asymmetric mismatch is for several reasons:
+ // * it's the only way to match the existing (non-falcon) behavior
+ // * If our cursor is before the <, we want to match the tag.
+ // example: |<foo > will find "foo" as the nearest tag.
+ // So we need to use start here (not content start)
+ // * If our cursor is between two tags, we want to match the NEXT one, not the previous one
+ // example: <bar >|<foo> should match foo, not bar
+
+ if (MXMLData.contains(unit.getAbsoluteStart(), unit.getContentEnd(), offset))
+ {
+ ret = unit;
+ }
+ // if we find a unit that starts after the offset, then it must
+ // be the "first one after", so return it
+ else if (unit.getAbsoluteStart() >= offset)
+ {
+ ret = unit;
+ }
+ }
+
+ // If we found something, update the cursor for the next search
+ if (ret != null)
+ cursor.setCursor(offset, ret.getIndex());
+ return ret;
+ }
+
+ /**
+ * Get the unit that should be referenced when looking at what tags contain
+ * this offset (i.e. tags that are opened and not closed before this offset)
+ *
+ * @param offset test offset
+ * @return reference unit for containment searches
+ */
+ public IMXMLUnitData findContainmentReferenceUnit(int offset)
+ {
+ return findNearestUnit(offset);
+ }
+
+ /**
+ * Get the unit that contains this offset
+ *
+ * @param offset test offset
+ * @return the containing unit (or null if no unit contains this offset)
+ */
+ public IMXMLUnitData findUnitContainingOffset(int offset)
+ {
+ IMXMLUnitData unit = findNearestUnit(offset);
+ if (unit != null && unit.containsOffset(offset))
+ return unit;
+
+ return null;
+ }
+
+ /**
+ * Get the open, close, or empty tag that contains this offset. Note that if
+ * offset is inside a text node, this returns null. If you want the
+ * surrounding tag in that case, use
+ * findTagOrSurroundingTagContainingOffset.
+ *
+ * @param offset test offset
+ * @return the containing tag (or null, if no tag contains this offset)
+ */
+ public IMXMLTagData findTagContainingOffset(int offset)
+ {
+ IMXMLUnitData unit = findUnitContainingOffset(offset);
+ if (unit != null && unit.isTag())
+ return (IMXMLTagData)unit;
+
+ return null;
+ }
+
+ @Override
+ public IMXMLTagData findTagOrSurroundingTagContainingOffset(int offset)
+ {
+ IMXMLUnitData unit = findUnitContainingOffset(offset);
+ if (unit != null)
+ {
+ if (unit.isTag())
+ {
+ return (IMXMLTagData)unit;
+ }
+ else if (unit.isText())
+ {
+ IMXMLTagData containingTag = unit.getContainingTag(unit.getAbsoluteStart());
+ return containingTag;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the open or empty tag whose attribute list contains this offset. A
+ * tag's attribute list extends from after the tag name + first whitespace
+ * until before the closing ">" or "/>".
+ *
+ * @param offset test offset
+ * @return tag whose attribute list contains this offset (or null, if the
+ * offset isn't in any attribute lists
+ */
+ public IMXMLTagData findAttributeListContainingOffset(int offset)
+ {
+ IMXMLTagData tag = findTagContainingOffset(offset);
+ if (tag != null && tag.isOpenTag())
+ return tag.isOffsetInAttributeList(offset) ? tag : null;
+
+ return null;
+ }
+
+ /**
+ * Test whether the offset is contained within the range from start to end.
+ * This test excludes the start position and includes the end position,
+ * which is how you want things to work for code hints.
+ *
+ * @param start start of the range (excluded)
+ * @param end end of the range (included)
+ * @param offset test offset
+ * @return true iff the offset is contained in the range
+ */
+ public static boolean contains(int start, int end, int offset)
+ {
+ return start < offset && end >= offset;
+ }
+
+ @Override
+ public IMXMLTagData getRootTag()
+ {
+ int n = units.length;
+ for (int i = 0; i < n; i++)
+ {
+ IMXMLUnitData unit = units[i];
+ if (unit instanceof IMXMLTagData)
+ return (IMXMLTagData)unit;
+ }
+ return null;
+ }
+
+ @Override
+ public int getEnd()
+ {
+ final int n = getNumUnits();
+ return n > 0 ? getUnit(n - 1).getAbsoluteEnd() : 0;
+ }
+
+ public Cursor getCursor()
+ {
+ return cursor;
+ }
+
+ /**
+ * Verifies that all units (plus all attributes on units that are tags) have
+ * their source location information set.
+ * <p>
+ * This is used only in asserts.
+ */
+ public boolean verify()
+ {
+ for (IMXMLUnitData unit : getUnits())
+ {
+ ((MXMLUnitData)unit).verify();
+ }
+
+ return true;
+ }
+
+ // For debugging only.
+ void dumpUnits()
+ {
+ for (IMXMLUnitData unit : getUnits())
+ {
+ System.out.println(((MXMLUnitData)unit).toDumpString());
+ }
+ }
+
+ /**
+ * For debugging only.
+ */
+ @Override
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+
+ IMXMLUnitData[] units = getUnits();
+ int n = units.length;
+ for (int i = 0; i < n; i++)
+ {
+ // Display the unit's index as, for example, [3].
+ sb.append('[');
+ sb.append(i);
+ sb.append(']');
+
+ sb.append(' ');
+
+ // Display the unit's information.
+ sb.append(units[i].toString());
+
+ sb.append('\n');
+ }
+
+ return sb.toString();
+ }
+
+ public static void main(String[] args)
+ {
+ final FileSpecification fileSpec = new FileSpecification(args[0]);
+ final MXMLTokenizer tokenizer = new MXMLTokenizer(fileSpec);
+ List<MXMLToken> tokens = null;
+ try
+ {
+ tokens = tokenizer.parseTokens(fileSpec.createReader());
+
+ // Build tags and attributes from the tokens.
+ final MXMLData mxmlData = new MXMLData(tokens, tokenizer.getPrefixMap(), fileSpec);
+
+ mxmlData.dumpUnits();
+ }
+ catch (FileNotFoundException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ finally
+ {
+ IOUtils.closeQuietly(tokenizer);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDataManager.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDataManager.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDataManager.java
index 3364a26..19cacfa 100644
--- a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDataManager.java
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDataManager.java
@@ -22,7 +22,6 @@ package org.apache.flex.compiler.internal.mxml;
import org.apache.flex.compiler.filespecs.IFileSpecification;
import org.apache.flex.compiler.internal.caches.MXMLDataCache;
import org.apache.flex.compiler.mxml.IMXMLDataManager;
-import org.apache.flex.compiler.mxml.MXMLData;
/**
* The {@code MXMLDataManager} of the {@code IWorkspace}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDatabindingData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDatabindingData.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDatabindingData.java
new file mode 100644
index 0000000..da7f720
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDatabindingData.java
@@ -0,0 +1,58 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import java.util.ListIterator;
+
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
+import org.apache.flex.compiler.mxml.IMXMLDatabindingData;
+import org.apache.flex.compiler.mxml.IMXMLDatabindingValue;
+import org.apache.flex.compiler.parsing.IASToken;
+
+/**
+ * Represents a databinding expression found within content of MXML
+ */
+public class MXMLDatabindingData extends MXMLUnitData implements
+ IMXMLDatabindingData
+{
+ /**
+ * Constructor.
+ */
+ MXMLDatabindingData(MXMLToken start, ListIterator<MXMLToken> iterator)
+ {
+ bindingValue = new MXMLDatabindingValue(start, iterator);
+
+ setOffsets(bindingValue.getAbsoluteStart(), bindingValue.getAbsoluteEnd());
+ setLine(start.getLine());
+ setColumn(start.getColumn());
+ }
+
+ private IMXMLDatabindingValue bindingValue;
+
+ //
+ // IMXMLDatabindingData implementations
+ //
+
+ @Override
+ public IASToken[] getDatabindingContent()
+ {
+ return bindingValue.getDatabindingContent();
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDatabindingValue.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDatabindingValue.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDatabindingValue.java
new file mode 100644
index 0000000..2eee4d1
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLDatabindingValue.java
@@ -0,0 +1,113 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import java.util.ArrayList;
+import java.util.ListIterator;
+
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
+import org.apache.flex.compiler.mxml.IMXMLDatabindingValue;
+import org.apache.flex.compiler.mxml.IMXMLTagAttributeData;
+import org.apache.flex.compiler.mxml.IMXMLTextData.TextType;
+import org.apache.flex.compiler.parsing.IASToken;
+
+/**
+ * Represents a databinding expression found within an attribute value
+ */
+public class MXMLDatabindingValue extends MXMLTagAttributeValue implements
+ IMXMLDatabindingValue
+{
+ /**
+ * Constructor.
+ */
+ MXMLDatabindingValue(MXMLToken start, ListIterator<MXMLToken> iterator, IMXMLTagAttributeData parent)
+ {
+ super(parent);
+
+ setStart(start.getStart());
+ setColumn(start.getColumn());
+ setLine(start.getLine());
+
+ while (iterator.hasNext())
+ {
+ MXMLToken token = iterator.next();
+
+ setEnd(token.getEnd());
+
+ if (token.isASToken())
+ tokens.add(token);
+ else
+ break;
+ }
+ }
+
+ /**
+ * Constructor.
+ */
+ MXMLDatabindingValue(MXMLToken start, ListIterator<MXMLToken> iterator)
+ {
+ this(start, iterator, null);
+ }
+
+ private ArrayList<IASToken> tokens = new ArrayList<IASToken>(5);
+
+ //
+ // IMXMLTextData implementations
+ //
+
+ @Override
+ public String getContent()
+ {
+ StringBuilder builder = new StringBuilder();
+
+ final int size = tokens.size();
+ IASToken lastToken = null;
+ for (int i = 0; i < size; i++)
+ {
+ IASToken currentToken = tokens.get(i);
+ if (lastToken != null)
+ {
+ int spaces = currentToken.getStart() - lastToken.getEnd();
+ for (int s = 0; s < spaces; s++)
+ builder.append(" ");
+ }
+ builder.append(currentToken.getText());
+ lastToken = currentToken;
+ }
+
+ return builder.toString();
+ }
+
+ @Override
+ public TextType getTextType()
+ {
+ return TextType.DATABINDING;
+ }
+
+ //
+ // IMXMLDatabindingData implementations
+ //
+
+ @Override
+ public IASToken[] getDatabindingContent()
+ {
+ return tokens.toArray(new IASToken[0]);
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLEntityData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLEntityData.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLEntityData.java
new file mode 100644
index 0000000..96604cd
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLEntityData.java
@@ -0,0 +1,80 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
+import org.apache.flex.compiler.mxml.IMXMLEntityData;
+
+public class MXMLEntityData extends MXMLTextData implements IMXMLEntityData
+{
+ /**
+ * Constructor.
+ */
+ MXMLEntityData(MXMLToken textToken)
+ {
+ super(textToken);
+
+ type = textToken.getType();
+ }
+
+ private int type;
+
+ //
+ // Object overrides
+ //
+
+ // This method is only used for debugging.
+ @Override
+ public String toString()
+ {
+ String s = getCompilableText();
+
+ s = s.replaceAll("\n", "\\\\n");
+ s = s.replaceAll("\r", "\\\\r");
+ s = s.replaceAll("\t", "\\\\t");
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(type);
+ sb.append(" \"");
+ sb.append(s);
+ sb.append("\"");
+ return sb.toString();
+ }
+
+ //
+ // MXMLTextData overrides
+ //
+
+ @Override
+ public String getCompilableText()
+ {
+ return getDecodedContent();
+ }
+
+ //
+ // IMXMLEntityData implementations
+ //
+
+ @Override
+ public String getDecodedContent()
+ {
+ return MXMLEntityValue.getDecodedContent(getContents(), type);
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLEntityValue.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLEntityValue.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLEntityValue.java
new file mode 100644
index 0000000..29d7db7
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLEntityValue.java
@@ -0,0 +1,144 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.flex.compiler.mxml.IMXMLEntityValue;
+import org.apache.flex.compiler.mxml.IMXMLTagAttributeData;
+import org.apache.flex.compiler.mxml.IMXMLTextData.TextType;
+import org.apache.flex.compiler.parsing.IMXMLToken;
+import org.apache.flex.compiler.parsing.MXMLTokenTypes;
+
+public class MXMLEntityValue extends MXMLTagAttributeValue implements
+ IMXMLEntityValue
+{
+ private static final Map<String, String> NAMED_ENTITIES;
+
+ static
+ {
+ NAMED_ENTITIES = new HashMap<String, String>(5);
+
+ NAMED_ENTITIES.put("&", "&");
+ NAMED_ENTITIES.put("'", "'");
+ NAMED_ENTITIES.put(">", ">");
+ NAMED_ENTITIES.put("<", "<");
+ NAMED_ENTITIES.put(""", "\"");
+
+ // TODO HTML 4 supports about 250 named characters
+ // HTML 5 supports about 2500. How many should MXML support
+ // beyond these required 5? What did Xerces/mxmlc support?
+ }
+
+ static final String getDecodedContent(String content, int type)
+ {
+ switch (type)
+ {
+ case MXMLTokenTypes.TOKEN_ENTITY:
+ {
+ return NAMED_ENTITIES.get(content);
+ }
+ case MXMLTokenTypes.TOKEN_HEX_ENTITY:
+ {
+ //thanks to the lexer, we are always: �
+ //strip off the first 3 chars and the trailing semicolon
+ return String.valueOf(Integer.parseInt(content.substring(3, content.length() - 1), 16));
+ }
+ case MXMLTokenTypes.TOKEN_DECIMAL_ENTITY:
+ {
+ //thanks to the lexer, we are always: &#\21267;
+ //strip off the first 3 chars and the trailing semicolon
+ return String.valueOf(Integer.parseInt(content.substring(3, content.length() - 1)));
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Constructor.
+ */
+ MXMLEntityValue(IMXMLToken token, IMXMLTagAttributeData parent)
+ {
+ super(parent);
+
+ content = token.getText();
+ type = token.getType();
+
+ setStart(token.getStart());
+ setEnd(token.getEnd());
+ setColumn(token.getColumn());
+ setLine(token.getLine());
+ }
+
+ private final String content;
+
+ /**
+ * Token type which tells us what kind of entity we are dealing with
+ */
+ private final int type;
+
+ //
+ // Object overrides
+ //
+
+ // For debugging only. This format is nice in the Eclipse debugger.
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("|");
+ sb.append(getContent());
+ sb.append("| ");
+ sb.append(getLine());
+ sb.append(" ");
+ sb.append(getColumn());
+
+ return sb.toString();
+ }
+
+ //
+ // IMXMLTagAttributeValue implementations
+ //
+
+ @Override
+ public String getContent()
+ {
+ return content;
+ }
+
+ @Override
+ public TextType getTextType()
+ {
+ return TextType.ENTITY;
+ }
+
+ //
+ // IMXMLEntityValue implementations
+ //
+
+ @Override
+ public String getDecodedContent()
+ {
+ return getDecodedContent(content, type);
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLInstructionData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLInstructionData.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLInstructionData.java
new file mode 100644
index 0000000..da2fec4
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLInstructionData.java
@@ -0,0 +1,97 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import org.apache.flex.compiler.mxml.IMXMLInstructionData;
+import org.apache.flex.compiler.parsing.IMXMLToken;
+
+public class MXMLInstructionData extends MXMLUnitData implements
+ IMXMLInstructionData
+{
+ /**
+ * Constructor.
+ */
+ MXMLInstructionData(IMXMLToken token)
+ {
+ instructionText = token.getText();
+
+ setOffsets(token.getStart(), token.getEnd());
+ setColumn(token.getColumn());
+ setLine(token.getLine());
+ }
+
+ private String instructionText;
+
+ //
+ // Object overrides
+ //
+
+ // For debugging only. This format is nice in the Eclipse debugger.
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append('|');
+ sb.append(getInstructionText());
+ sb.append('|');
+
+ sb.append(' ');
+
+ // Display line, column, start, and end as "17:5 160-188".
+ sb.append(super.toString());
+
+ return sb.toString();
+ }
+
+ //
+ // MXMLUnitData overrides
+ //
+
+ // For debugging only. This format is nice in a text file.
+ @Override
+ public String toDumpString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(super.toDumpString());
+
+ sb.append('\t');
+
+ sb.append('"');
+ sb.append(getInstructionText());
+ sb.append('"');
+
+ return sb.toString();
+ }
+
+ //
+ // IMXMLInstructionData implementations
+ //
+
+ /**
+ * Returns the raw processing instruction. It is up to clients to parse
+ * this.
+ */
+ public String getInstructionText()
+ {
+ return instructionText;
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLNamespaceAttributeData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLNamespaceAttributeData.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLNamespaceAttributeData.java
new file mode 100644
index 0000000..4c00837
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLNamespaceAttributeData.java
@@ -0,0 +1,64 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import java.util.Collection;
+import java.util.ListIterator;
+
+import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
+import org.apache.flex.compiler.mxml.IMXMLNamespaceAttributeData;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+
+/**
+ * Represents an xmlns style namespace import found within the MXML language
+ */
+public class MXMLNamespaceAttributeData extends MXMLTagAttributeData implements
+ IMXMLNamespaceAttributeData
+{
+ /**
+ * Constructor.
+ */
+ MXMLNamespaceAttributeData(MXMLToken nameToken, ListIterator<MXMLToken> tokenIterator, MXMLDialect mxmlDialect, IFileSpecification spec, Collection<ICompilerProblem> problems)
+ {
+ super(nameToken, tokenIterator, mxmlDialect, spec, problems);
+
+ if (attributeName.startsWith("xmlns:"))
+ prefix = attributeName.substring(6);
+ }
+
+ private String prefix = "";
+
+ //
+ // IMXMLNamepsaceAttributeData implementations
+ //
+
+ @Override
+ public String getNamespacePrefix()
+ {
+ return prefix;
+ }
+
+ @Override
+ public String getNamespace()
+ {
+ return getRawValue();
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLNamespaceMapping.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLNamespaceMapping.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLNamespaceMapping.java
new file mode 100644
index 0000000..272fcc7
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLNamespaceMapping.java
@@ -0,0 +1,76 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import org.apache.flex.compiler.mxml.IMXMLNamespaceMapping;
+
+/**
+ * This class stores a MXML-namespace-URI-to-manifest-file mapping.
+ */
+public class MXMLNamespaceMapping implements IMXMLNamespaceMapping
+{
+ public MXMLNamespaceMapping(String uri, String manifestFileName)
+ {
+ assert uri != null;
+ assert manifestFileName != null;
+ this.uri = uri;
+ this.manifestFileName = manifestFileName;
+ }
+
+ private String uri;
+ private String manifestFileName;
+
+ @Override
+ public String getURI()
+ {
+ return uri;
+ }
+
+ @Override
+ public String getManifestFileName()
+ {
+ return manifestFileName;
+ }
+
+ /**
+ * For debugging.
+ *
+ * @return Debug string representation of this object.
+ */
+ @Override
+ public String toString()
+ {
+ return uri + "->" + manifestFileName;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ return true;
+ if (!(obj instanceof MXMLNamespaceMapping))
+ return false;
+ MXMLNamespaceMapping other = (MXMLNamespaceMapping)obj;
+ if (!(uri.equals(other.uri)))
+ return false;
+ return manifestFileName.equals(other.manifestFileName);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLStateSplitter.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLStateSplitter.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLStateSplitter.java
new file mode 100644
index 0000000..3c78c33
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLStateSplitter.java
@@ -0,0 +1,86 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import java.util.Collection;
+
+import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
+import org.apache.flex.compiler.parsing.IMXMLToken;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.problems.SyntaxProblem;
+
+/**
+ * Simple utility for parsing attribute.state phrases.
+ */
+public class MXMLStateSplitter
+{
+ /**
+ * Constructor.
+ */
+ public MXMLStateSplitter(IMXMLToken nameToken, MXMLDialect mxmlDialect, Collection<ICompilerProblem> problems, IFileSpecification fileSpec)
+ {
+ // Is there a dot in the name?
+ String name = nameToken.getText();
+ int i = name.indexOf('.');
+ if (i >= 0)
+ {
+ if (mxmlDialect != null && mxmlDialect.isEqualToOrAfter(MXMLDialect.MXML_2009))
+ {
+ baseName = name.substring(0, i);
+ stateName = name.substring(i + 1);
+ stateNameOffset = i + 1;
+ }
+ else
+ {
+ stateNameOffset = -1;
+ baseName = name;
+ stateName = null;
+
+ // TODO: I don't think is going to make the right kind of "problem"
+ // This is how the old code worked, but I think it will give a strange message
+ if (problems != null && fileSpec != null)
+ problems.add(new SyntaxProblem((MXMLToken)nameToken, "Spark state overrides not supported by current language version"));
+ }
+ }
+ else
+ {
+ // no dot.
+ baseName = name;
+ stateNameOffset = -1;
+ stateName = null;
+ }
+ }
+
+ /**
+ * The part of the name before the dot, or the whole name if no dot.
+ */
+ public final String baseName;
+
+ /**
+ * What's after the first dot (state override), or null if no dot
+ */
+ public final String stateName;
+
+ /**
+ * offset of state name, where zero is the first character in the name
+ */
+ public final int stateNameOffset;
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bec3ba00/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagAttributeData.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagAttributeData.java b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagAttributeData.java
new file mode 100644
index 0000000..b921919
--- /dev/null
+++ b/compiler/src/org/apache/flex/compiler/internal/mxml/MXMLTagAttributeData.java
@@ -0,0 +1,637 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.mxml;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ListIterator;
+
+import org.apache.flex.compiler.common.ISourceLocation;
+import org.apache.flex.compiler.common.PrefixMap;
+import org.apache.flex.compiler.common.SourceLocation;
+import org.apache.flex.compiler.common.XMLName;
+import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.internal.parsing.ISourceFragment;
+import org.apache.flex.compiler.internal.parsing.mxml.MXMLToken;
+import org.apache.flex.compiler.mxml.IMXMLTagAttributeData;
+import org.apache.flex.compiler.mxml.IMXMLTagAttributeValue;
+import org.apache.flex.compiler.mxml.IMXMLTagData;
+import org.apache.flex.compiler.mxml.IMXMLTextValue;
+import org.apache.flex.compiler.parsing.IMXMLToken;
+import org.apache.flex.compiler.parsing.MXMLTokenTypes;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.problems.SyntaxProblem;
+
+/**
+ * Encapsulation of a tag attribute in MXML
+ */
+public class MXMLTagAttributeData extends SourceLocation implements
+ IMXMLTagAttributeData
+{
+ /**
+ * Constructor.
+ */
+ MXMLTagAttributeData(MXMLToken nameToken, ListIterator<MXMLToken> tokenIterator, MXMLDialect mxmlDialect, IFileSpecification spec, Collection<ICompilerProblem> problems)
+ {
+ setStart(nameToken.getStart());
+ setLine(nameToken.getLine());
+ setColumn(nameToken.getColumn());
+ setEnd(nameToken.getEnd());
+
+ // Deal with name if it is of the form name.state
+ MXMLStateSplitter splitState = new MXMLStateSplitter(nameToken, mxmlDialect, problems, spec);
+ attributeName = splitState.baseName;
+ if (splitState.stateName != null)
+ {
+ stateName = splitState.stateName;
+ stateStart = nameToken.getStart() + splitState.stateNameOffset;
+ }
+
+ MXMLToken token = null;
+
+ // Look for "=" token
+ if (tokenIterator.hasNext())
+ {
+ token = tokenIterator.next();
+
+ if (token.getType() != MXMLTokenTypes.TOKEN_EQUALS)
+ {
+ problems.add(new SyntaxProblem(token));
+ // need to restore the token position in the error
+ // case to handle error recovery otherwise the any
+ // trees after this won't be created
+ tokenIterator.previous();
+ return;
+ }
+
+ valueStart = token.getEnd() + 1; //set the attributes start to right after the equals until we have a value
+ valueLine = token.getLine();
+ valueColumn = token.getColumn();
+ }
+
+ // Look for value token
+ ArrayList<IMXMLTagAttributeValue> values = new ArrayList<IMXMLTagAttributeValue>(3);
+ while (tokenIterator.hasNext())
+ {
+ token = tokenIterator.next();
+ if (token.getType() == MXMLTokenTypes.TOKEN_DATABINDING_START)
+ {
+ values.add(new MXMLDatabindingValue(token, tokenIterator, this));
+ }
+ else if (token.getType() == MXMLTokenTypes.TOKEN_STRING)
+ {
+ values.add(new MXMLTextValue(token, this));
+ }
+ else if (token.isEntity())
+ {
+ values.add(new MXMLEntityValue(token, this));
+ }
+ else
+ {
+ if (!MXMLToken.isTagEnd(token.getType()) && token.getType() != MXMLTokenTypes.TOKEN_NAME)
+ {
+ // if we error out early, push back token - it may be start of next tag
+ // this is "pre-falcon" repair that was lost
+ tokenIterator.previous();
+ problems.add(new SyntaxProblem(token));
+ }
+ else
+ {
+ tokenIterator.previous();
+ }
+ break;
+ }
+ }
+
+ this.values = values.toArray(new MXMLTagAttributeValue[0]);
+
+ if (this.values.length > 0)
+ {
+ //set the start value
+ IMXMLTagAttributeValue value = this.values[0];
+ valueStart = value.getAbsoluteStart();
+ valueLine = value.getLine();
+ valueColumn = value.getColumn();
+ final int valueEnd = getValueEnd();
+ setEnd(valueEnd + 1);
+ }
+ }
+
+ /**
+ * The MXML tag that contains this attribute
+ */
+ protected IMXMLTagData parent;
+
+ /**
+ * The name of this attribute.
+ */
+ protected String attributeName;
+
+ /**
+ * The offset at which the attribute value starts
+ */
+ protected int valueStart;
+
+ /**
+ * The line on which the attribute value starts
+ */
+ protected int valueLine;
+
+ /**
+ * The column at which the attribute value starts
+ */
+ protected int valueColumn;
+
+ /**
+ * Array of values inside this attribute data.
+ */
+ private IMXMLTagAttributeValue[] values = new IMXMLTagAttributeValue[0];
+
+ /**
+ * The name of this state, if it exists
+ */
+ protected String stateName;
+
+ /**
+ * The offset at which the optional state starts
+ */
+ protected int stateStart;
+
+ /**
+ * The URI specified by this attribute's prefix.
+ */
+ protected String uri;
+
+ //
+ // Object overrides.
+ //
+
+ // For debugging only. This format is nice in the Eclipse debugger.
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ buildAttributeString(false);
+ return sb.toString();
+ }
+
+ /**
+ * For unit tests only.
+ *
+ * @return name value and offsets in string form
+ */
+ public String buildAttributeString(boolean skipSrcPath)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append(getName());
+ sb.append('=');
+ sb.append('"');
+ sb.append(getRawValue());
+ sb.append('"');
+
+ sb.append(' ');
+
+ // Display line, column, start, and end as "17:5 160-188".
+ if (skipSrcPath)
+ sb.append(getOffsetsString());
+ else
+ sb.append(super.toString());
+ return sb.toString();
+ }
+
+ //
+ // Other methods
+ //
+
+ @Override
+ public IMXMLTagData getParent()
+ {
+ return parent;
+ }
+
+ /**
+ * Sets this attribute's tag.
+ *
+ * @param parent MXML tag containing this attribute
+ */
+ public void setParent(IMXMLTagData parent)
+ {
+ this.parent = parent;
+ setSourcePath(parent.getSourcePath());
+ }
+
+ /**
+ * Adjust all associated offsets by the adjustment amount
+ *
+ * @param offsetAdjustment amount to add to offsets
+ */
+ public void adjustOffsets(int offsetAdjustment)
+ {
+ if (attributeName != null)
+ {
+ setStart(getAbsoluteStart() + offsetAdjustment);
+ setEnd(getAbsoluteEnd() + offsetAdjustment);
+ }
+
+ if (hasValue())
+ {
+ valueStart += offsetAdjustment;
+ for (int i = 0; i < values.length; i++)
+ {
+ ((MXMLTagAttributeValue)values[i]).setStart(values[i].getAbsoluteStart() + offsetAdjustment);
+ ((MXMLTagAttributeValue)values[i]).setEnd(values[i].getAbsoluteEnd() + offsetAdjustment);
+ }
+ }
+
+ if (stateName != null)
+ stateStart += offsetAdjustment;
+ }
+
+ @Override
+ public String getName()
+ {
+ return attributeName;
+ }
+
+ @Override
+ public String getStateName()
+ {
+ return stateName != null ? stateName : "";
+ }
+
+ /**
+ * Checks whether this attribute is associated with a state.
+ *
+ * @return True if a state association exists.
+ */
+ public boolean hasState()
+ {
+ return stateName != null;
+ }
+
+ @Override
+ public boolean hasValue()
+ {
+ return values.length > 0;
+ }
+
+ @Override
+ public IMXMLTagAttributeValue[] getValues()
+ {
+ return values;
+ }
+
+ /**
+ * Get the attribute value as a String (with quotes)
+ *
+ * @return attribute value (with quotes)
+ */
+ public String getValueWithQuotes()
+ {
+ StringBuilder value = new StringBuilder();
+
+ final int size = values.length;
+ IMXMLTagAttributeValue lastData = null;
+ for (int i = 0; i < size; i++)
+ {
+ IMXMLTagAttributeValue data = values[i];
+ if (lastData != null)
+ {
+ for (int s = 0; s < data.getAbsoluteStart() - lastData.getAbsoluteEnd(); i++)
+ {
+ value.append(" ");
+ }
+ }
+ value.append(data.getContent());
+ }
+
+ return value.toString();
+ }
+
+ @Override
+ public String getRawValue()
+ {
+ String value = getValueWithQuotes();
+
+ if (value != null && value.length() > 0)
+ {
+ // length can be one in case of invalid data and then the substring() call fails
+ // so, handle it here
+ if (value.charAt(0) == value.charAt(value.length() - 1) && value.length() != 1)
+ value = value.substring(1, value.length() - 1);
+ else
+ value = value.substring(1);
+ }
+
+ return value;
+ }
+
+ @Override
+ public ISourceFragment[] getValueFragments(Collection<ICompilerProblem> problems)
+ {
+ String value = getRawValue();
+ ISourceLocation location = getValueLocation();
+ MXMLDialect mxmlDialect = getMXMLDialect();
+
+ return EntityProcessor.parse(value, location, mxmlDialect, problems);
+ }
+
+ /**
+ * Returns the value of the raw token (without quotes) only if only one
+ * value exists and it is a string value New clients should take into
+ * account that multiple values exist inside of an attribute value
+ *
+ * @return a value token, or null
+ */
+ // TODO Rename to getValueToken()
+ public IMXMLToken getRawValueToken()
+ {
+ if (hasState() && values.length == 1 && values[0] instanceof IMXMLTextValue)
+ {
+ String value = getRawValue();
+ if (value != null)
+ {
+ return new MXMLToken(MXMLTokenTypes.TOKEN_STRING, getValueStart() + 1, getValueStart() + 1 + value.length(), -1, -1, value);
+ }
+ }
+ return null;
+ }
+
+ public IFileSpecification getSource()
+ {
+ return getParent().getSource();
+ }
+
+ /**
+ * Get this unit's line number.
+ *
+ * @return end offset
+ */
+ public final int getNameLine()
+ {
+ return getLine();
+ }
+
+ /**
+ * Get this unit's column number.
+ *
+ * @return end offset
+ */
+ public final int getNameColumn()
+ {
+ return getColumn();
+ }
+
+ public int getNameStart()
+ {
+ return getAbsoluteStart();
+ }
+
+ /**
+ * Get this attribute's name's end offset
+ *
+ * @return name end offset
+ */
+ public int getNameEnd()
+ {
+ return getAbsoluteStart() + attributeName.length();
+ }
+
+ @Override
+ public int getValueStart()
+ {
+ return hasValue() ? valueStart + 1 : 0;
+ }
+
+ @Override
+ public int getValueEnd()
+ {
+ if (hasValue())
+ {
+ String lastContent = values[values.length - 1].getContent();
+
+ if (lastContent.charAt(0) == lastContent.charAt(lastContent.length() - 1))
+ return getValueStart() + lastContent.length() - 2;
+
+ return getValueStart() + lastContent.length();
+ }
+
+ // If there is no valid "end", then we must return -1. Callers depend on this.
+ // See MXMLTagData.findArttributeContainingOffset for an example
+ return -1;
+ }
+
+ @Override
+ public int getValueLine()
+ {
+ return hasValue() ? valueLine : 0;
+ }
+
+ @Override
+ public int getValueColumn()
+ {
+ return hasValue() ? valueColumn + 1 : 0;
+ }
+
+ @Override
+ public SourceLocation getValueLocation()
+ {
+ return new SourceLocation(getSourcePath(), getValueStart(), getValueEnd(), getValueLine(), getValueColumn());
+ }
+
+ /**
+ * Get this attribute's state start offset if a state token is present other
+ * wise zero.
+ *
+ * @return state start offset or zero
+ */
+ public int getStateStart()
+ {
+ return stateName != null ? stateStart : 0;
+ }
+
+ /**
+ * Get this attribute's state tokens end offset if a state token is present
+ * other wise zero.
+ *
+ * @return state start offset or zero
+ */
+ public int getStateEnd()
+ {
+ return stateName != null ? stateStart + stateName.length() : 0;
+ }
+
+ /**
+ * Does this value have a closing quote character?
+ *
+ * @return true if this value has a closing quote character
+ */
+ protected boolean valueIsWellFormed()
+ {
+ // If there is a value, it came from a string token. We know (from the
+ // RawTagTokenizer) that this means it starts with a quote character. If
+ // it ends with the same quote character, it's well formed.
+ if (hasValue())
+ {
+ String lastContent = values[values.length - 1].getContent();
+ return (lastContent.charAt(0) == lastContent.charAt(lastContent.length() - 1));
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the {@link PrefixMap} that represents all prefix->namespace
+ * mappings are in play on this tag. For example, if a parent tag defines
+ * <code>xmlns:m="falcon"</code> and this tag defines
+ * <code>xmlns:m="eagle"</code> then in this prefix map, m will equal
+ * "eagle"
+ *
+ * @return a {@link PrefixMap} or null
+ */
+ public PrefixMap getCompositePrefixMap()
+ {
+ return parent.getCompositePrefixMap();
+ }
+
+ /**
+ * Does the offset fall inside the bounds of the attribute name?
+ *
+ * @param offset test offset
+ * @return true if the offset falls within the attribute name
+ */
+ public boolean isInsideName(int offset)
+ {
+ if (attributeName != null)
+ return MXMLData.contains(getNameStart(), getNameEnd(), offset);
+
+ return false;
+ }
+
+ public boolean isInsideStateName(int offset)
+ {
+ if (stateName != null)
+ return MXMLData.contains(getStateStart(), getStateEnd(), offset);
+
+ return false;
+ }
+
+ /**
+ * Does the offset fall inside the bounds of the attribute value?
+ *
+ * @param offset test offset
+ * @return true if the offset falls within the attribute value
+ */
+ public boolean isInsideValue(int offset)
+ {
+ if (hasValue())
+ return MXMLData.contains(getValueStart() - 1, getValueEnd(), offset);
+
+ return false;
+ }
+
+ @Override
+ public String getPrefix()
+ {
+ String name = getName();
+ int i = name.indexOf(':');
+ return i != -1 ? name.substring(0, i) : null;
+ }
+
+ @Override
+ public String getShortName()
+ {
+ String name = getName();
+ int i = name.indexOf(':');
+ return i != -1 ? name.substring(i + 1) : name;
+ }
+
+ @Override
+ public XMLName getXMLName()
+ {
+ return new XMLName(getURI(), getShortName());
+ }
+
+ @Override
+ public String getURI()
+ {
+ if (uri == null)
+ {
+ //walk up our chain to find the correct uri for our namespace. first one wins
+ String prefix = getPrefix();
+ if (prefix == null)
+ return null;
+
+ IMXMLTagData lookingAt = parent;
+
+ // For attributes with prefix, parent's parent can be null if
+ // parent is the root tag
+ while (lookingAt != null && lookingAt.getParent() != null)
+ {
+ PrefixMap depth = lookingAt.getParent().getPrefixMapForData(lookingAt);
+ if (depth != null && depth.containsPrefix(prefix))
+ {
+ uri = depth.getNamespaceForPrefix(prefix);
+ break;
+ }
+
+ lookingAt = lookingAt.getParentTag();
+ }
+ }
+
+ return uri;
+ }
+
+ void invalidateURI()
+ {
+ uri = null;
+ }
+
+ @Override
+ public MXMLDialect getMXMLDialect()
+ {
+ return getParent().getParent().getMXMLDialect();
+ }
+
+ @Override
+ public boolean isSpecialAttribute(String name)
+ {
+ String languageURI = getMXMLDialect().getLanguageNamespace();
+
+ return getName().equals(name) && (getPrefix() == null || getURI() == languageURI);
+ }
+
+ /**
+ * Verifies that this attrobite has its source location information set.
+ * <p>
+ * This is used only in asserts.
+ */
+ public boolean verify()
+ {
+ // Verify the source location.
+ assert getSourcePath() != null : "Attribute has null source path: " + toString();
+ assert getStart() != UNKNOWN : "Attribute has unknown start: " + toString();
+ assert getEnd() != UNKNOWN : "Attribute has unknown end: " + toString();
+ assert getLine() != UNKNOWN : "Attribute has unknown line: " + toString();
+ assert getColumn() != UNKNOWN : "Attribute has unknown column: " + toString();
+
+ return true;
+ }
+}