org.eclipse.jdt.core.dom.SimpleName#getParent ( )源码实例Demo

下面列出了org.eclipse.jdt.core.dom.SimpleName#getParent ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

/**
 * {@inheritDoc}
 */
@Override
public boolean visit(SimpleName node) {
	if (node.getParent() instanceof VariableDeclarationFragment)
		return super.visit(node);
	if (node.getParent() instanceof SingleVariableDeclaration)
		return super.visit(node);

	IBinding binding= node.resolveBinding();
	if (!(binding instanceof IVariableBinding))
		return super.visit(node);

	binding= ((IVariableBinding)binding).getVariableDeclaration();
	if (ASTResolving.isWriteAccess(node)) {
		List<SimpleName> list;
		if (fResult.containsKey(binding)) {
			list= fResult.get(binding);
		} else {
			list= new ArrayList<SimpleName>();
		}
		list.add(node);
		fResult.put(binding, list);
	}

	return super.visit(node);
}
 
@Override
public boolean consumes(SemanticToken token) {

	// 1: match types
	SimpleName name= token.getNode();
	ASTNode node= name.getParent();
	int nodeType= node.getNodeType();
	if (nodeType != ASTNode.SIMPLE_TYPE && nodeType != ASTNode.QUALIFIED_TYPE)
		return false;

	// 2: match type arguments
	StructuralPropertyDescriptor locationInParent= node.getLocationInParent();
	if (locationInParent == ParameterizedType.TYPE_ARGUMENTS_PROPERTY)
		return true;

	return false;
}
 
@Override
public boolean consumes(SemanticToken token) {

	// 1: match types
	SimpleName name= token.getNode();
	ASTNode node= name.getParent();
	int nodeType= node.getNodeType();
	if (nodeType != ASTNode.SIMPLE_TYPE && nodeType != ASTNode.THIS_EXPRESSION && nodeType != ASTNode.QUALIFIED_TYPE  && nodeType != ASTNode.QUALIFIED_NAME && nodeType != ASTNode.TYPE_DECLARATION && nodeType != ASTNode.METHOD_INVOCATION)
		return false;
	while (nodeType == ASTNode.QUALIFIED_NAME) {
		node= node.getParent();
		nodeType= node.getNodeType();
		if (nodeType == ASTNode.IMPORT_DECLARATION)
			return false;
	}

	// 2: match classes
	IBinding binding= token.getBinding();
	if (binding instanceof ITypeBinding) {
		ITypeBinding typeBinding= (ITypeBinding) binding;
		// see also ClassHighlighting
		return typeBinding.isClass() && (typeBinding.getModifiers() & Modifier.ABSTRACT) != 0;
	}

	return false;
}
 
源代码4 项目: eclipse.jdt.ls   文件: SemanticHighlightings.java
@Override
public boolean consumes(SemanticToken token) {

	// 1: match types
	SimpleName name = token.getNode();
	ASTNode node = name.getParent();
	int nodeType = node.getNodeType();
	if (nodeType != ASTNode.METHOD_INVOCATION && nodeType != ASTNode.SIMPLE_TYPE && nodeType != ASTNode.QUALIFIED_TYPE && nodeType != ASTNode.QUALIFIED_NAME && nodeType != ASTNode.QUALIFIED_NAME
			&& nodeType != ASTNode.ENUM_DECLARATION) {
		return false;
	}
	while (nodeType == ASTNode.QUALIFIED_NAME) {
		node = node.getParent();
		nodeType = node.getNodeType();
		if (nodeType == ASTNode.IMPORT_DECLARATION) {
			return false;
		}
	}

	// 2: match enums
	IBinding binding = token.getBinding();
	return binding instanceof ITypeBinding && ((ITypeBinding) binding).isEnum();
}
 
源代码5 项目: eclipse.jdt.ls   文件: SemanticHighlightings.java
@Override
public boolean consumes(SemanticToken token) {

	// 1: match types
	SimpleName name = token.getNode();
	ASTNode node = name.getParent();
	int nodeType = node.getNodeType();
	if (nodeType != ASTNode.SIMPLE_TYPE && nodeType != ASTNode.QUALIFIED_TYPE && nodeType != ASTNode.QUALIFIED_NAME && nodeType != ASTNode.TYPE_DECLARATION) {
		return false;
	}
	while (nodeType == ASTNode.QUALIFIED_NAME) {
		node = node.getParent();
		nodeType = node.getNodeType();
		if (nodeType == ASTNode.IMPORT_DECLARATION) {
			return false;
		}
	}

	// 2: match interfaces
	IBinding binding = token.getBinding();
	return binding instanceof ITypeBinding && ((ITypeBinding) binding).isInterface();
}
 
源代码6 项目: eclipse.jdt.ls   文件: SemanticHighlightings.java
@Override
public boolean consumes(SemanticToken token) {

	// 1: match types
	SimpleName name = token.getNode();
	ASTNode node = name.getParent();
	int nodeType = node.getNodeType();
	if (nodeType != ASTNode.SIMPLE_TYPE && nodeType != ASTNode.QUALIFIED_TYPE && nodeType != ASTNode.QUALIFIED_NAME && nodeType != ASTNode.ANNOTATION_TYPE_DECLARATION && nodeType != ASTNode.MARKER_ANNOTATION
			&& nodeType != ASTNode.NORMAL_ANNOTATION && nodeType != ASTNode.SINGLE_MEMBER_ANNOTATION) {
		return false;
	}
	while (nodeType == ASTNode.QUALIFIED_NAME) {
		node = node.getParent();
		nodeType = node.getNodeType();
		if (nodeType == ASTNode.IMPORT_DECLARATION) {
			return false;
		}
	}

	// 2: match annotations
	IBinding binding = token.getBinding();
	return binding instanceof ITypeBinding && ((ITypeBinding) binding).isAnnotation();
}
 
源代码7 项目: eclipse.jdt.ls   文件: TempOccurrenceAnalyzer.java
@Override
public boolean visit(SimpleName node){
	if (node.getParent() instanceof VariableDeclaration){
		if (((VariableDeclaration)node.getParent()).getName() == node)
		 {
			return true; //don't include declaration
		}
	}

	if (fTempBinding != null && fTempBinding == node.resolveBinding()) {
		if (fIsInJavadoc) {
			fJavadocNodes.add(node);
		} else {
			fReferenceNodes.add(node);
		}
	}

	return true;
}
 
@Override
public boolean visit(SimpleName node){
	if (node.getParent() instanceof VariableDeclaration){
		if (((VariableDeclaration)node.getParent()).getName() == node)
			return true; //don't include declaration
	}

	if (fTempBinding != null && fTempBinding == node.resolveBinding()) {
		if (fIsInJavadoc)
			fJavadocNodes.add(node);
		else
			fReferenceNodes.add(node);
	}

	return true;
}
 
private void updateSimpleName(ASTRewrite rewriter, ParameterInfo pi, SimpleName node, List<SingleVariableDeclaration> enclosingParameters, IJavaProject project) {
	AST ast= rewriter.getAST();
	IBinding binding= node.resolveBinding();
	Expression replacementNode= fParameterObjectFactory.createFieldReadAccess(pi, getParameterName(), ast, project, false, null);
	if (binding instanceof IVariableBinding) {
		IVariableBinding variable= (IVariableBinding) binding;
		if (variable.isParameter() && variable.getName().equals(getNameInScope(pi, enclosingParameters))) {
			rewriter.replace(node, replacementNode, null);
		}
	} else {
		ASTNode parent= node.getParent();
		if (!(parent instanceof QualifiedName || parent instanceof FieldAccess || parent instanceof SuperFieldAccess)) {
			if (node.getIdentifier().equals(getNameInScope(pi, enclosingParameters))) {
				rewriter.replace(node, replacementNode, null);
			}
		}
	}
}
 
源代码10 项目: eclipse.jdt.ls   文件: SemanticHighlightings.java
@Override
public boolean consumes(SemanticToken token) {

	// 1: match types
	SimpleName name = token.getNode();
	ASTNode node = name.getParent();
	int nodeType = node.getNodeType();
	if (nodeType != ASTNode.SIMPLE_TYPE && nodeType != ASTNode.THIS_EXPRESSION && nodeType != ASTNode.QUALIFIED_TYPE && nodeType != ASTNode.QUALIFIED_NAME && nodeType != ASTNode.TYPE_DECLARATION
			&& nodeType != ASTNode.METHOD_INVOCATION) {
		return false;
	}
	while (nodeType == ASTNode.QUALIFIED_NAME) {
		node = node.getParent();
		nodeType = node.getNodeType();
		if (nodeType == ASTNode.IMPORT_DECLARATION) {
			return false;
		}
	}

	// 2: match classes
	IBinding binding = token.getBinding();
	if (binding instanceof ITypeBinding) {
		ITypeBinding typeBinding = (ITypeBinding) binding;
		// see also ClassHighlighting
		return typeBinding.isClass() && (typeBinding.getModifiers() & Modifier.ABSTRACT) != 0;
	}

	return false;
}
 
private boolean isEnhancedForStatementVariable(Statement statement, SimpleName name) {
	if (statement instanceof EnhancedForStatement) {
		EnhancedForStatement forStatement= (EnhancedForStatement) statement;
		SingleVariableDeclaration param= forStatement.getParameter();
		return param.getType() == name.getParent(); // strange recovery, see https://bugs.eclipse.org/180456
	}
	return false;
}
 
private static boolean hasSideEffect(SimpleName reference) {
	ASTNode parent= reference.getParent();
	while (parent instanceof QualifiedName) {
		parent= parent.getParent();
	}
	if (parent instanceof FieldAccess) {
		parent= parent.getParent();
	}

	ASTNode node= null;
	int nameParentType= parent.getNodeType();
	if (nameParentType == ASTNode.ASSIGNMENT) {
		Assignment assignment= (Assignment) parent;
		node= assignment.getRightHandSide();
	} else if (nameParentType == ASTNode.SINGLE_VARIABLE_DECLARATION) {
		SingleVariableDeclaration decl= (SingleVariableDeclaration)parent;
		node= decl.getInitializer();
		if (node == null)
			return false;
	} else if (nameParentType == ASTNode.VARIABLE_DECLARATION_FRAGMENT) {
		node= parent;
	} else {
		return false;
	}

	ArrayList<Expression> sideEffects= new ArrayList<Expression>();
	node.accept(new SideEffectFinder(sideEffects));
	return sideEffects.size() > 0;
}
 
源代码13 项目: api-mining   文件: JavaApproximateTypeInferencer.java
/**
 * Visits {@link SimpleName} AST nodes. Resolves the binding of the simple
 * name and looks for it in the {@link #variableScope} map. If the binding
 * is found, this is a reference to a variable.
 *
 * @param node
 *            the node to visit
 */
@Override
public boolean visit(final SimpleName node) {
	if (node.getParent().getNodeType() == ASTNode.METHOD_INVOCATION) {
		final MethodInvocation invocation = (MethodInvocation) node.getParent();
		if (invocation.getName() == node) {
			return true;
		}
	}
	addBindingData(node.getIdentifier(), node, variableNames.get(node));
	return true;
}
 
private Expression getSimpleNameReceiver(SimpleName node) {
	Expression receiver;
	if (node.getParent() instanceof QualifiedName && node.getLocationInParent() == QualifiedName.NAME_PROPERTY) {
		receiver= ((QualifiedName) node.getParent()).getQualifier();
	} else if (node.getParent() instanceof FieldAccess && node.getLocationInParent() == FieldAccess.NAME_PROPERTY) {
		receiver= ((FieldAccess) node.getParent()).getExpression();
	} else {
		//TODO other cases? (ThisExpression, SuperAccessExpression, ...)
		receiver= null;
	}
	if (receiver instanceof ThisExpression)
		return null;
	else
		return receiver;
}
 
@Override
public final void endVisit(final SimpleName node) {
	final ASTNode parent= node.getParent();
	if (!(parent instanceof ImportDeclaration) && !(parent instanceof PackageDeclaration) && !(parent instanceof AbstractTypeDeclaration)) {
		final IBinding binding= node.resolveBinding();
		if (binding instanceof IVariableBinding && !(parent instanceof MethodDeclaration))
			endVisit((IVariableBinding) binding, null, node);
		else if (binding instanceof ITypeBinding && parent instanceof MethodDeclaration)
			endVisit((ITypeBinding) binding, node);
	}
}
 
/**
 * Remove the field or variable declaration including the initializer.
 * @param rewrite the AST rewriter to use
 * @param reference a reference to the variable to remove
 * @param group the text edit group to use
 */
private void removeVariableReferences(ASTRewrite rewrite, SimpleName reference, TextEditGroup group) {
	ASTNode parent= reference.getParent();
	while (parent instanceof QualifiedName) {
		parent= parent.getParent();
	}
	if (parent instanceof FieldAccess) {
		parent= parent.getParent();
	}

	int nameParentType= parent.getNodeType();
	if (nameParentType == ASTNode.ASSIGNMENT) {
		Assignment assignment= (Assignment) parent;
		Expression rightHand= assignment.getRightHandSide();

		ASTNode assignParent= assignment.getParent();
		if (assignParent.getNodeType() == ASTNode.EXPRESSION_STATEMENT && rightHand.getNodeType() != ASTNode.ASSIGNMENT) {
			removeVariableWithInitializer(rewrite, rightHand, assignParent, group);
		}	else {
			rewrite.replace(assignment, rewrite.createCopyTarget(rightHand), group);
		}
	} else if (nameParentType == ASTNode.SINGLE_VARIABLE_DECLARATION) {
		rewrite.remove(parent, group);
	} else if (nameParentType == ASTNode.VARIABLE_DECLARATION_FRAGMENT) {
		VariableDeclarationFragment frag= (VariableDeclarationFragment) parent;
		ASTNode varDecl= frag.getParent();
		List<VariableDeclarationFragment> fragments;
		if (varDecl instanceof VariableDeclarationExpression) {
			fragments= ((VariableDeclarationExpression) varDecl).fragments();
		} else if (varDecl instanceof FieldDeclaration) {
			fragments= ((FieldDeclaration) varDecl).fragments();
		} else {
			fragments= ((VariableDeclarationStatement) varDecl).fragments();
		}
		Expression initializer = frag.getInitializer();
		ArrayList<Expression> sideEffects= new ArrayList<Expression>();
		if (initializer != null) {
			initializer.accept(new SideEffectFinder(sideEffects));
		}
		boolean sideEffectInitializer= sideEffects.size() > 0;
		if (fragments.size() == fUnusedNames.length) {
			if (fForceRemove) {
				rewrite.remove(varDecl, group);
				return;
			}
			if (parent.getParent() instanceof FieldDeclaration) {
				rewrite.remove(varDecl, group);
				return;
			}
			if (sideEffectInitializer) {
				Statement[] wrapped= new Statement[sideEffects.size()];
				for (int i= 0; i < wrapped.length; i++) {
					Expression sideEffect= sideEffects.get(i);
					Expression movedInit= (Expression) rewrite.createMoveTarget(sideEffect);
					wrapped[i]= rewrite.getAST().newExpressionStatement(movedInit);
				}
				StatementRewrite statementRewrite= new StatementRewrite(rewrite, new ASTNode[] { varDecl });
				statementRewrite.replace(wrapped, group);
			} else {
				rewrite.remove(varDecl, group);
			}
		} else {
			if (fForceRemove) {
				rewrite.remove(frag, group);
				return;
			}
			//multiple declarations in one line
			ASTNode declaration = parent.getParent();
			if (declaration instanceof FieldDeclaration) {
				rewrite.remove(frag, group);
				return;
			}
			if (declaration instanceof VariableDeclarationStatement) {
				splitUpDeclarations(rewrite, group, frag, (VariableDeclarationStatement) declaration, sideEffects);
				rewrite.remove(frag, group);
				return;
			}
			if (declaration instanceof VariableDeclarationExpression) {
				//keep constructors and method invocations
				if (!sideEffectInitializer){
					rewrite.remove(frag, group);
				}
			}
		}
	} else if (nameParentType == ASTNode.POSTFIX_EXPRESSION || nameParentType == ASTNode.PREFIX_EXPRESSION) {
		Expression expression= (Expression)parent;
		ASTNode expressionParent= expression.getParent();
		if (expressionParent.getNodeType() == ASTNode.EXPRESSION_STATEMENT) {
			removeStatement(rewrite, expressionParent, group);
		} else {
			rewrite.remove(expression, group);
		}
	}
}
 
源代码17 项目: JDeodorant   文件: MethodDeclarationUtility.java
public static AbstractVariable createVariable(SimpleName simpleName, AbstractVariable rightPart) {
	IBinding binding = simpleName.resolveBinding();
	if(binding != null && binding.getKind() == IBinding.VARIABLE) {
		IVariableBinding variableBinding = (IVariableBinding)binding;
		AbstractVariable currentVariable = null;
		if(rightPart == null)
			currentVariable = new PlainVariable(variableBinding);
		else
			currentVariable = new CompositeVariable(variableBinding, rightPart);
		
		if(simpleName.getParent() instanceof QualifiedName) {
			QualifiedName qualifiedName = (QualifiedName)simpleName.getParent();
			Name qualifier = qualifiedName.getQualifier();
			if(qualifier instanceof SimpleName) {
				SimpleName qualifierSimpleName = (SimpleName)qualifier;
				if(!qualifierSimpleName.equals(simpleName))
					return createVariable(qualifierSimpleName, currentVariable);
				else
					return currentVariable;
			}
			else if(qualifier instanceof QualifiedName) {
				QualifiedName qualifiedName2 = (QualifiedName)qualifier;
				return createVariable(qualifiedName2.getName(), currentVariable);
			}
		}
		else if(simpleName.getParent() instanceof FieldAccess) {
			FieldAccess fieldAccess = (FieldAccess)simpleName.getParent();
			Expression fieldAccessExpression = fieldAccess.getExpression();
			if(fieldAccessExpression instanceof FieldAccess) {
				FieldAccess fieldAccess2 = (FieldAccess)fieldAccessExpression;
				return createVariable(fieldAccess2.getName(), currentVariable);
			}
			else if(fieldAccessExpression instanceof SimpleName) {
				SimpleName fieldAccessSimpleName = (SimpleName)fieldAccessExpression;
				return createVariable(fieldAccessSimpleName, currentVariable);
			}
			else if(fieldAccessExpression instanceof ThisExpression) {
				return currentVariable;
			}
		}
		else {
			return currentVariable;
		}
	}
	return null;
}
 
源代码18 项目: JDeodorant   文件: ControlVariable.java
private static List<ASTNode> getValueContributingModifiers(SimpleName variable)
{
	List<ASTNode> allVariableModifiers  = getAllVariableModifiersInParentMethod(variable);
	List<ASTNode> contributingModifiers = new ArrayList<ASTNode>();
	boolean noModifierInLowerScope      = true;
	MethodDeclaration parentMethod      = AbstractLoopUtilities.findParentMethodDeclaration(variable);
	// create a list of all parents of the specified variable until the root method
	List<ASTNode> variableParents = new ArrayList<ASTNode>();
	ASTNode currentVariableParent = variable.getParent();
	while (currentVariableParent != null && currentVariableParent != parentMethod)
	{
		variableParents.add(currentVariableParent);
		currentVariableParent = currentVariableParent.getParent();
	}
	variableParents.add(parentMethod);
	// we traverse allVariableModifiers and build a list of nodes that will influence the final value
	Iterator<ASTNode> it = allVariableModifiers.iterator();
	while (it.hasNext())
	{
		ASTNode currentNode = it.next();
		boolean currentNodeAdded = false;
		// if the current node is the declaration or an assignment, the list restarts the modifiers. if it is a plus, minus, times, or divide equals, then it adds to the modifiers
		if (currentNode instanceof VariableDeclaration)
		{
			contributingModifiers = new ArrayList<ASTNode>();
			contributingModifiers.add(currentNode);
			currentNodeAdded = true;
			noModifierInLowerScope = true;
		}
		else if (currentNode instanceof Assignment)
		{
			Assignment assignment = (Assignment) currentNode;
			Assignment.Operator operator = assignment.getOperator();
			if (operator == Assignment.Operator.ASSIGN)
			{
				contributingModifiers = new ArrayList<ASTNode>();
				contributingModifiers.add(currentNode);
				currentNodeAdded = true;
				noModifierInLowerScope = true;
			}
			else if (operator == Assignment.Operator.PLUS_ASSIGN ||
					operator == Assignment.Operator.MINUS_ASSIGN ||
					operator == Assignment.Operator.TIMES_ASSIGN ||
					operator == Assignment.Operator.DIVIDE_ASSIGN)
			{
				contributingModifiers.add(currentNode);
				currentNodeAdded = true;
			}				
		}
		else if (currentNode instanceof PrefixExpression || currentNode instanceof PostfixExpression)
		{
			contributingModifiers.add(currentNode);
			currentNodeAdded = true;
		}
		else if (currentNode instanceof MethodInvocation)
		{
			MethodInvocation currentMethodInvocation = (MethodInvocation) currentNode;
			AbstractLoopBindingInformation bindingInformation = AbstractLoopBindingInformation.getInstance();
			String currentMethodBindingKey = currentMethodInvocation.resolveMethodBinding().getMethodDeclaration().getKey();
			if (bindingInformation.updateMethodValuesContains(currentMethodBindingKey))
			{
				contributingModifiers.add(currentNode);
				currentNodeAdded = true;
			}
		}
		// if currentNode was added, move up through it's parents until the first block or conditional parent and check if it is in the variableParents list, if not, it is in a lower scope
		if (currentNodeAdded)
		{
			ASTNode currentNodeParent = currentNode.getParent();
			while (currentNodeParent != null)
			{
				if ((currentNodeParent instanceof MethodDeclaration || currentNodeParent instanceof IfStatement || currentNodeParent instanceof ForStatement ||
						currentNodeParent instanceof WhileStatement || currentNodeParent instanceof DoStatement || currentNodeParent instanceof EnhancedForStatement ||
						currentNodeParent instanceof SwitchStatement || currentNodeParent instanceof TryStatement))
				{
					if (!variableParents.contains(currentNodeParent))
					{
						noModifierInLowerScope = false;
					}
					break;
				}
				currentNodeParent = currentNodeParent.getParent();
			}
		}
	}
	// return constructed list if all modifiers are in same or higher scope
	if (noModifierInLowerScope)
	{
		return contributingModifiers;
	}
	return new ArrayList<ASTNode>();
}
 
@Override
public final boolean visit(final SimpleName node) {
	Assert.isNotNull(node);
	final AST ast= node.getAST();
	final ASTRewrite rewrite= fRewrite;
	final IBinding binding= node.resolveBinding();
	if (binding instanceof ITypeBinding) {
		ITypeBinding type= (ITypeBinding) binding;
		String name= fTargetRewrite.getImportRewrite().addImport(type.getTypeDeclaration());
		if (name != null && name.indexOf('.') != -1) {
			fRewrite.replace(node, ASTNodeFactory.newName(ast, name), null);
			return false;
		}
	}
	if (Bindings.equals(fTarget, binding))
		if (fAnonymousClass > 0) {
			final ThisExpression target= ast.newThisExpression();
			target.setQualifier(ast.newSimpleName(fTargetType.getElementName()));
			fRewrite.replace(node, target, null);
		} else
			rewrite.replace(node, ast.newThisExpression(), null);
	else if (binding instanceof IVariableBinding) {
		final IVariableBinding variable= (IVariableBinding) binding;
		final IMethodBinding method= fDeclaration.resolveBinding();
		ITypeBinding declaring= variable.getDeclaringClass();
		if (method != null) {
			if (declaring != null && Bindings.isSuperType(declaring, method.getDeclaringClass(), false)) {
				declaring= declaring.getTypeDeclaration();
				if (JdtFlags.isStatic(variable))
					rewrite.replace(node, ast.newQualifiedName(ASTNodeFactory.newName(ast, fTargetRewrite.getImportRewrite().addImport(declaring)), ast.newSimpleName(node.getFullyQualifiedName())), null);
				else {
					final FieldAccess access= ast.newFieldAccess();
					access.setExpression(ast.newSimpleName(fTargetName));
					access.setName(ast.newSimpleName(node.getFullyQualifiedName()));
					rewrite.replace(node, access, null);
				}
			} else if (!(node.getParent() instanceof QualifiedName) && JdtFlags.isStatic(variable) && !fStaticImports.contains(variable) && !Checks.isEnumCase(node.getParent())) {
				rewrite.replace(node, ast.newQualifiedName(ASTNodeFactory.newName(ast, fTargetRewrite.getImportRewrite().addImport(declaring)), ast.newSimpleName(node.getFullyQualifiedName())), null);
			}
		}
	}
	return false;
}
 
private static boolean isFormalParameterInEnhancedForStatement(SimpleName name) {
	return name.getParent() instanceof SingleVariableDeclaration && name.getParent().getLocationInParent() == EnhancedForStatement.PARAMETER_PROPERTY;
}