blob: 0fa93d6818b1bb1f8335390641a42fe31e59faaf [file] [log] [blame]
/*
*
* 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.royale.compiler.internal.mxml;
import static org.apache.royale.compiler.constants.IMXMLCoreConstants.*;
import java.util.Collection;
import org.apache.royale.compiler.common.ISourceLocation;
import org.apache.royale.compiler.internal.parsing.ISourceFragment;
import org.apache.royale.compiler.internal.parsing.SourceFragment;
import org.apache.royale.compiler.internal.parsing.mxml.MXMLToken;
import org.apache.royale.compiler.mxml.IMXMLTextData;
import org.apache.royale.compiler.parsing.MXMLTokenTypes;
import org.apache.royale.compiler.problems.ICompilerProblem;
/**
* Encapsulation of a block of text in MXML
*/
public class MXMLTextData extends MXMLUnitData implements IMXMLTextData
{
/**
* Constructor.
*/
public MXMLTextData(MXMLToken textToken)
{
text = textToken.getText();
setOffsets(textToken.getStart(), textToken.getEnd());
setLine(textToken.getLine());
setColumn(textToken.getColumn());
setEndLine(textToken.getEndLine());
setEndColumn(textToken.getEndColumn());
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;
}
}
}
/**
* 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();
}
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();
}
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();
}
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;
}
}