/* * Copyright 2003-2011 JetBrains s.r.o. * * Licensed 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 jetbrains.mps.typesystem.newTypesystem.structure; import java.util.Iterator; import java.util.List; import java.util.Set; public class Matcher { public static <Meta, Target> MatchResult<Meta, Target> match(Type<Meta, Target> type1, Type<Meta, Target> type2) { MatchResult<Meta, Target> result = new MatchResult<Meta, Target>(); if (type1 == type2) return result; if (type1 == null || type2 == null) return MatchResult.FALSE; //vars if (type1.isVar() || type2.isVar()) { result.addEquation(type1, type2); return result; } //matching if (type1.getMeta() != type2.getMeta()) { return MatchResult.FALSE; } Set<String> referenceRoles = type1.getReferenceRoles(); referenceRoles.addAll(type2.getReferenceRoles()); for (String role : referenceRoles) { if (type1.getReferent(role) != type2.getReferent(role)) { return MatchResult.FALSE; } } //children Set<String> childRoles = type1.getChildRoles(); childRoles.addAll(type2.getChildRoles()); for (String role : childRoles) { List<Type<Meta, Target>> children1 = type1.getChildren(role); List<Type<Meta, Target>> children2 = type2.getChildren(role); if (children1.size() != children2.size()) { return MatchResult.FALSE; } for (Iterator<Type<Meta, Target>> i1 = children1.iterator(), i2 = children2.iterator(); i1.hasNext() && i2.hasNext();) { Type<Meta, Target> child1 = i1.next(); Type<Meta, Target> child2 = i2.next(); MatchResult<Meta, Target> childResult = match(child1, child2); if (!childResult.isCorrectMatch()) { return MatchResult.FALSE; } else { result.addEquations(childResult); } } } return result; } }