001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.corext.refactoring.typeconstraints;
011:
012: import java.util.HashMap;
013: import java.util.Map;
014:
015: import org.eclipse.jdt.core.dom.ITypeBinding;
016:
017: public class TypeConstraintFactory implements ITypeConstraintFactory {
018:
019: private Map/*<ConstraintVariable, Map<ConstraintVariable, Map<ConstraintOperator, SimpleTypeConstraint>>*/fSimpleConstraints = new HashMap();
020: private Map/*<ConstraintVariable, Map<String, CompositeOrTypeConstraint>>*/fOrConstraints = new HashMap();
021:
022: protected static final boolean PRINT_STATS = false;
023: protected int fNrCreated = 0;
024: protected int fNrFiltered = 0;
025: protected int fNrRetrieved = 0;
026:
027: // Only to be called by the createXXXConstraint() methods
028: private SimpleTypeConstraint createSimpleTypeConstraint(
029: ConstraintVariable v1, ConstraintVariable v2,
030: ConstraintOperator operator) {
031: if (fSimpleConstraints.containsKey(v1)) {
032: Map m2 = (Map) fSimpleConstraints.get(v1);
033: if (m2.containsKey(v2)) {
034: Map m3 = (Map) m2.get(v2);
035: if (m3.containsKey(operator)) {
036: if (PRINT_STATS)
037: fNrRetrieved++;
038: if (PRINT_STATS)
039: dumpStats();
040: return (SimpleTypeConstraint) m3.get(operator);
041: } else {
042: return storeConstraint(v1, v2, operator, m3);
043: }
044: } else {
045: Map m3 = new HashMap();
046: m2.put(v2, m3);
047: return storeConstraint(v1, v2, operator, m3);
048: }
049: } else {
050: Map m2 = new HashMap();
051: fSimpleConstraints.put(v1, m2);
052: Map m3 = new HashMap();
053: m2.put(v2, m3);
054: return storeConstraint(v1, v2, operator, m3);
055: }
056: }
057:
058: private SimpleTypeConstraint storeConstraint(ConstraintVariable v1,
059: ConstraintVariable v2, ConstraintOperator operator, Map m3) {
060: SimpleTypeConstraint constraint = new SimpleTypeConstraint(v1,
061: v2, operator);
062: m3.put(operator, constraint);
063: if (PRINT_STATS)
064: fNrCreated++;
065: if (PRINT_STATS)
066: dumpStats();
067: return constraint;
068: }
069:
070: public ITypeConstraint[] createConstraint(ConstraintVariable v1,
071: ConstraintVariable v2, ConstraintOperator operator) {
072: if (filter(v1, v2, operator)) {
073: return new ITypeConstraint[0];
074: } else {
075: return new ITypeConstraint[] { createSimpleTypeConstraint(
076: v1, v2, operator) };
077: }
078: }
079:
080: public ITypeConstraint[] createSubtypeConstraint(
081: ConstraintVariable v1, ConstraintVariable v2) {
082: return createConstraint(v1, v2, ConstraintOperator
083: .createSubTypeOperator());
084: }
085:
086: public ITypeConstraint[] createStrictSubtypeConstraint(
087: ConstraintVariable v1, ConstraintVariable v2) {
088: return createConstraint(v1, v2, ConstraintOperator
089: .createStrictSubtypeOperator());
090: }
091:
092: public ITypeConstraint[] createEqualsConstraint(
093: ConstraintVariable v1, ConstraintVariable v2) {
094: return createConstraint(v1, v2, ConstraintOperator
095: .createEqualsOperator());
096: }
097:
098: public ITypeConstraint[] createDefinesConstraint(
099: ConstraintVariable v1, ConstraintVariable v2) {
100: return createConstraint(v1, v2, ConstraintOperator
101: .createDefinesOperator());
102: }
103:
104: /**
105: * {@inheritDoc}
106: * Avoid creating constraints involving primitive types and self-constraints.
107: */
108: public boolean filter(ConstraintVariable v1, ConstraintVariable v2,
109: ConstraintOperator operator) {
110: if ((v1.getBinding() != null && v1.getBinding().isPrimitive()
111: && v2.getBinding() != null && v2.getBinding()
112: .isPrimitive())
113: || v1 == v2) {
114: if (PRINT_STATS)
115: fNrFiltered++;
116: if (PRINT_STATS)
117: dumpStats();
118: return true;
119: }
120: return false;
121: }
122:
123: /*
124: * (non-Javadoc)
125: *
126: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.ITypeConstraintFactory#createCompositeOrTypeConstraint(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.ITypeConstraint[])
127: */
128: public CompositeOrTypeConstraint createCompositeOrTypeConstraint(
129: ITypeConstraint[] constraints) {
130: ConstraintVariable left = ((SimpleTypeConstraint) constraints[0])
131: .getLeft();
132: String bounds = ""; //$NON-NLS-1$
133: for (int i = 0; i < constraints.length; i++) {
134: ConstraintVariable right = ((SimpleTypeConstraint) constraints[i])
135: .getRight();
136: ITypeBinding binding = right.getBinding();
137: String typeName = binding.getQualifiedName();
138: bounds = bounds + typeName + ","; //$NON-NLS-1$
139: }
140:
141: if (fOrConstraints.containsKey(left)) {
142: Map m2 = (Map) fOrConstraints.get(left);
143: if (m2.containsKey(bounds)) {
144: if (PRINT_STATS)
145: fNrRetrieved++;
146: if (PRINT_STATS)
147: dumpStats();
148: return (CompositeOrTypeConstraint) m2.get(bounds);
149: } else {
150: CompositeOrTypeConstraint constraint = new CompositeOrTypeConstraint(
151: constraints);
152: m2.put(bounds, constraint);
153: if (PRINT_STATS)
154: dumpStats();
155: if (PRINT_STATS)
156: fNrCreated++;
157: return constraint;
158: }
159: } else {
160: Map m2 = new HashMap();
161: fOrConstraints.put(left, m2);
162: CompositeOrTypeConstraint constraint = new CompositeOrTypeConstraint(
163: constraints);
164: m2.put(bounds, constraint);
165: if (PRINT_STATS)
166: dumpStats();
167: if (PRINT_STATS)
168: fNrCreated++;
169: return constraint;
170: }
171: }
172:
173: protected void dumpStats() {
174: System.out
175: .println("Constraints: " + fNrCreated + " created, " + fNrRetrieved + " retrieved, " + fNrFiltered + " filtered"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
176: }
177:
178: }
|