public void test_childOperationsOnNull() throws Exception { this.addNodeById("8758390115029078425"); this.addNodeById("5815925154349132136"); this.addNodeById("2166349271756548530"); SNode nullNode = null; Assert.assertNull(SNodeOperations.getContainingLinkDeclaration(nullNode)); Assert.assertNull(SNodeOperations.getContainingLinkRole(nullNode)); }
public void test_childContaininLinksForSpecializedChildren() throws Exception { this.addNodeById("8758390115029078425"); this.addNodeById("5815925154349132136"); this.addNodeById("2166349271756548530"); Assert.assertEquals( SLinkOperations.findLinkDeclaration( "jetbrains.mps.lang.smodelTests.structure.Child", "grandChild_0_1"), SNodeOperations.getContainingLinkDeclaration( SNodeOperations.cast( this.getNodeById("2600026384779198859"), "jetbrains.mps.lang.smodelTests.structure.GrandChild"))); }
public void execute_internal(EditorContext editorContext, SNode node) { if ((int) ListSequence.fromList(SLinkOperations.getTargets(node, "alternatives", true)).count() == 1) { List<SNode> parts = ListSequence.fromList( SLinkOperations.getTargets( ListSequence.fromList( SLinkOperations.getTargets(node, "alternatives", true)) .first(), "parts", true)) .toListSequence(); if ((int) ListSequence.fromList(parts).count() == 1) { SNodeOperations.replaceWithAnother(node, ListSequence.fromList(parts).first()); } else if ((int) ListSequence.fromList(parts).count() == 0) { SNodeOperations.deleteNode(node); } else if (!(LinkDeclaration_Behavior.call_isSingular_1213877254557( SNodeOperations.getContainingLinkDeclaration(node)))) { SNodeOperations.replaceWithAnother(node, ListSequence.fromList(parts).first()); final Wrappers._T<SNode> anchor = new Wrappers._T<SNode>(ListSequence.fromList(parts).removeElementAt(0)); ListSequence.fromList(parts) .visitAll( new IVisitor<SNode>() { public void visit(SNode it) { SNodeOperations.insertNextSiblingChild(anchor.value, it); anchor.value = it; } }); } } else if ((int) ListSequence.fromList(SLinkOperations.getTargets(node, "alternatives", true)).count() == 0) { SNodeOperations.deleteNode(node); } }
public void checkNode( final SNode node, LanguageErrorsComponent component, final IOperationContext operationContext, IScope scope) { final ConstraintsDescriptor newDescriptor = ConceptRegistry.getInstance().getConstraintsDescriptorNew(node.getConceptFqName()); final CheckingNodeContext checkingNodeContext = new jetbrains.mps.smodel.structure.CheckingNodeContext(); if (SNodeOperations.getParent(node) != null) { component.addDependency(SNodeOperations.getParent(node)); } if (SNodeOperations.getParent(node) != null && !(jetbrains.mps.smodel.SNodeOperations.isUnknown(SNodeOperations.getParent(node)))) { final SNode link = SNodeOperations.getContainingLinkDeclaration(node); if (link == null) { component.addError(node, "Child in a role with unknown link", null); return; } boolean canBeChild = component.runCheckingAction( new _FunctionTypes._return_P0_E0<Boolean>() { public Boolean invoke() { return ModelConstraintsManager.canBeChild( newDescriptor, node.getConceptFqName(), operationContext, SNodeOperations.getParent(node), link, checkingNodeContext); } }); if (!(canBeChild)) { SNode rule = getBreakingNodeAndClearContext(checkingNodeContext); component.addError( node, "Node " + node + " cannot be child of node " + SNodeOperations.getParent(node), rule); } } if (node.isRoot()) { boolean canBeRoot = component.runCheckingAction( new _FunctionTypes._return_P0_E0<Boolean>() { public Boolean invoke() { return ModelConstraintsManager.canBeRoot( newDescriptor, operationContext, node.getConceptFqName(), SNodeOperations.getModel(node), checkingNodeContext); } }); if (!(canBeRoot)) { SNode rule = getBreakingNodeAndClearContext(checkingNodeContext); component.addError(node, "Not rootable concept added as root", rule); } } for (SNode child : SNodeOperations.getChildren(node)) { component.addDependency(child); final SNode childConcept = SNodeOperations.getConceptDeclaration(child); final SNode childLink = SNodeOperations.getContainingLinkDeclaration(child); if (childLink == null) { continue; } boolean canBeParent = component.runCheckingAction( new _FunctionTypes._return_P0_E0<Boolean>() { public Boolean invoke() { return ModelConstraintsManager.canBeParent( newDescriptor, node, childConcept, childLink, operationContext, checkingNodeContext); } }); if (!(canBeParent)) { SNode rule = getBreakingNodeAndClearContext(checkingNodeContext); component.addError(node, "Node " + node + " cannot be parent of node " + child, rule); } // todo: do it right, with runCheckingAction! if (!(ModelConstraintsManager.canBeAncestor( node, childConcept, operationContext, checkingNodeContext))) { SNode rule = SNodeOperations.cast( getBreakingNodeAndClearContext(checkingNodeContext), "jetbrains.mps.lang.constraints.structure.ConstraintFunction_CanBeAnAncestor"); component.addError( child, "Concept " + SLinkOperations.getTarget( SNodeOperations.as( SNodeOperations.getParent(rule), "jetbrains.mps.lang.constraints.structure.ConceptConstraints"), "concept", false) + " cannot be ancestor of node " + child, rule); } } // Properties validation SNode concept = SNodeOperations.getConceptDeclaration(node); component.addDependency(concept); ConceptAndSuperConceptsScope chs = new ConceptAndSuperConceptsScope(concept); for (SNode parentConcept : chs.getConcepts()) { component.addDependency(parentConcept); } List<SNode> props = ((List<SNode>) chs.getNodes( new Condition<SNode>() { public boolean met(SNode n) { return SNodeOperations.isInstanceOf( n, "jetbrains.mps.lang.structure.structure.PropertyDeclaration"); } })); for (SNode p : ListSequence.fromList(props)) { final PropertySupport ps = PropertySupport.getPropertySupport(p); final String propertyName = SPropertyOperations.getString(p, "name"); if (propertyName == null) { LOG.error( "Property declaration has a null name, declaration id: " + p.getSNodeId() + ", model: " + SNodeOperations.getModel(p).getSModelFqName()); continue; } final String value = ps.fromInternalValue(node.getProperty(propertyName)); final PropertyConstraintsDescriptor propertyDescriptor = newDescriptor.getProperty(propertyName); boolean canSetValue = component.runCheckingAction( new _FunctionTypes._return_P0_E0<Boolean>() { public Boolean invoke() { return ps.canSetValue( propertyDescriptor, node, propertyName, value, operationContext.getScope()); } }); if (!(canSetValue)) { // RE-2426 Ñ disabling the "Property constraint violation for property" error messages /* // TODO this is a hack for anonymous classes if ("name".equals(SPropertyOperations.getString(p, "name")) && ("AnonymousClass".equals(SPropertyOperations.getString(concept, "name")) || "InternalAnonymousClass".equals(SPropertyOperations.getString(concept, "name")))) { continue; } // todo find a rule component.addError(node, "Property constraint violation for property \"" + SPropertyOperations.getString(p, "name") + "\"", null, new PropertyMessageTarget(SPropertyOperations.getString(p, "name"))); */ } } }
public static SNode processLeftTransform(SNode sourceNode, SNode result) { SNode nodeToProcess = PrecedenceUtil.getTargetForLeftTransform(sourceNode, result); // since BinaryOperations are left-associative we should perform complex LT then // BinaryOperations is "rightExpression" child of another BinaryOperations with same priority if (SNodeOperations.isInstanceOf( SNodeOperations.getParent(nodeToProcess), MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, "jetbrains.mps.baseLanguage.structure.BinaryOperation")) && SNodeOperations.getContainingLinkDeclaration(nodeToProcess) == SLinkOperations.findLinkDeclaration( MetaAdapterFactory.getContainmentLink( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, 0xfbdeb7a11bL, "rightExpression"))) { SNode parentBinaryOperation = SNodeOperations.cast( SNodeOperations.getParent(nodeToProcess), MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, "jetbrains.mps.baseLanguage.structure.BinaryOperation")); if (PrecedenceUtil.isSamePriority(parentBinaryOperation, result)) { SNodeOperations.replaceWithAnother(parentBinaryOperation, result); // <node> SLinkOperations.setTarget( result, MetaAdapterFactory.getContainmentLink( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, 0xfbdeb7a11bL, "rightExpression"), nodeToProcess); SLinkOperations.setTarget( result, MetaAdapterFactory.getContainmentLink( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, 0xfbdeb7a11cL, "leftExpression"), parentBinaryOperation); return result; } } SNodeOperations.replaceWithAnother(nodeToProcess, result); SLinkOperations.setTarget( result, MetaAdapterFactory.getContainmentLink( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, 0xfbdeb7a11bL, "rightExpression"), nodeToProcess); PrecedenceUtil.parenthesiseIfNecessary(result); return result; }
public static SNode parenthesiseIfNecessary(@NotNull SNode contextNode) { if (SNodeOperations.isInstanceOf( SNodeOperations.getParent(contextNode), MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, "jetbrains.mps.baseLanguage.structure.BinaryOperation"))) { SNode parentBinaryOperation = SNodeOperations.cast( SNodeOperations.getParent(contextNode), MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, "jetbrains.mps.baseLanguage.structure.BinaryOperation")); if (SNodeOperations.getContainingLinkDeclaration(contextNode) == SLinkOperations.findLinkDeclaration( MetaAdapterFactory.getContainmentLink( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, 0xfbdeb7a11bL, "rightExpression")) && isHigherPriority(parentBinaryOperation, contextNode)) { SNode result = SNodeFactoryOperations.replaceWithNewChild( contextNode, SNodeFactoryOperations.asInstanceConcept( MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfb4ed32b7fL, "jetbrains.mps.baseLanguage.structure.ParenthesizedExpression"))); SLinkOperations.setTarget( result, MetaAdapterFactory.getContainmentLink( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfb4ed32b7fL, 0xfb4ed32b80L, "expression"), contextNode); return result; } } else if (SNodeOperations.isInstanceOf( SNodeOperations.getParent(contextNode), MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940dabe4aL, "jetbrains.mps.baseLanguage.structure.CastExpression"))) { SNode parentCastExpression = SNodeOperations.cast( SNodeOperations.getParent(contextNode), MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940dabe4aL, "jetbrains.mps.baseLanguage.structure.CastExpression")); if (PrecedenceUtil.needsParensAroundCastExpression(parentCastExpression)) { SNode result = SNodeFactoryOperations.replaceWithNewChild( contextNode, SNodeFactoryOperations.asInstanceConcept( MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfb4ed32b7fL, "jetbrains.mps.baseLanguage.structure.ParenthesizedExpression"))); SLinkOperations.setTarget( result, MetaAdapterFactory.getContainmentLink( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfb4ed32b7fL, 0xfb4ed32b80L, "expression"), contextNode); return result; } } return contextNode; }
@NotNull public static SNode getTargetForRightTransform(@NotNull SNode contextNode) { SNode targetNode = contextNode; for (SNode parentNode = SNodeOperations.getParent(targetNode); parentNode != null && SNodeOperations.isInstanceOf( parentNode, MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c37f506fL, "jetbrains.mps.baseLanguage.structure.Expression")); parentNode = SNodeOperations.getParent(targetNode)) { if (SNodeOperations.isInstanceOf( parentNode, MetaAdapterFactory.getInterfaceConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, "jetbrains.mps.baseLanguage.structure.IMethodCall")) || SNodeOperations.isInstanceOf( parentNode, MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfb4ed32b7fL, "jetbrains.mps.baseLanguage.structure.ParenthesizedExpression"))) { // if parent expression is IMethodCall then targetNode is either actualArgument // or typeArgument (parameters of method call), so we should not go upper // same with ParenthesizedExpression break; } SNode targetContainingLink = SNodeOperations.getContainingLinkDeclaration(targetNode); if (SNodeOperations.isInstanceOf( parentNode, MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, "jetbrains.mps.baseLanguage.structure.BinaryOperation")) && targetContainingLink == SLinkOperations.findLinkDeclaration( MetaAdapterFactory.getContainmentLink( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, 0xfbdeb7a11cL, "leftExpression"))) { // if parent expression is BinaryOperation and target is left child of it // then we should rather transform current target break; } if (SNodeOperations.isInstanceOf( parentNode, MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, "jetbrains.mps.baseLanguage.structure.DotExpression")) && targetContainingLink == SLinkOperations.findLinkDeclaration( MetaAdapterFactory.getContainmentLink( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, 0x116b46a4416L, "operand"))) { // if parent expression is DotExpression and target is operang ("left" part of the // expression) // then we should rather transform current target break; } targetNode = SNodeOperations.cast( parentNode, MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c37f506fL, "jetbrains.mps.baseLanguage.structure.Expression")); } return targetNode; }
@NotNull public static SNode getTargetForLeftTransform( @NotNull SNode contextNode, @NotNull SNode resultNode) { int resultingExpressionPriority = getPriority(SNodeOperations.getConceptDeclaration(resultNode)).ordinal(); SNode targetNode = contextNode; for (SNode parentNode = SNodeOperations.getParent(targetNode); parentNode != null && SNodeOperations.isInstanceOf( parentNode, MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c37f506fL, "jetbrains.mps.baseLanguage.structure.Expression")) && getPriority( SNodeOperations.castConcept( SNodeOperations.getConceptDeclaration(parentNode), MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c37f506fL, "jetbrains.mps.baseLanguage.structure.Expression"))) .ordinal() < resultingExpressionPriority; parentNode = SNodeOperations.getParent(targetNode)) { if (SNodeOperations.isInstanceOf( parentNode, MetaAdapterFactory.getInterfaceConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, "jetbrains.mps.baseLanguage.structure.IMethodCall")) || SNodeOperations.isInstanceOf( parentNode, MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfb4ed32b7fL, "jetbrains.mps.baseLanguage.structure.ParenthesizedExpression"))) { // if parent expression is IMethodCall then targetNode is either actualArgument // or typeArgument (parameters of method call), so we should not go upper // same with ParenthesizedExpression break; } if (SNodeOperations.isInstanceOf( parentNode, MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, "jetbrains.mps.baseLanguage.structure.BinaryOperation")) && SNodeOperations.getContainingLinkDeclaration(targetNode) == SLinkOperations.findLinkDeclaration( MetaAdapterFactory.getContainmentLink( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, 0xfbdeb7a11bL, "rightExpression"))) { // if parent expression is BinaryOperation having higher priority and target is rhigh child // of it // then we should rather transform current target and add additional parenthesis around // resulting expression break; } targetNode = SNodeOperations.cast( parentNode, MetaAdapterFactory.getConcept( 0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c37f506fL, "jetbrains.mps.baseLanguage.structure.Expression")); } return targetNode; }