diff options
author | Vladimir Piskarev | 2017-04-19 14:47:14 +0000 |
---|---|---|
committer | Vladimir Piskarev | 2017-04-19 14:47:14 +0000 |
commit | 7c0577929394ec32fd550b23733c407cee339795 (patch) | |
tree | d849413d02c766b102fdc0f5a1dd79e920fe1627 | |
parent | 3dd93c9b31c6ba9be43e34fb59323b94c1a206f6 (diff) | |
download | org.eclipse.handly-7c0577929394ec32fd550b23733c407cee339795.tar.gz org.eclipse.handly-7c0577929394ec32fd550b23733c407cee339795.tar.xz org.eclipse.handly-7c0577929394ec32fd550b23733c407cee339795.zip |
Bug 515461 - Extract *ImplExtension interfaces for elements
11 files changed, 341 insertions, 251 deletions
diff --git a/org.eclipse.handly.examples.basic.ui.tests/src/org/eclipse/handly/internal/examples/basic/ui/model/FooWorkingCopyTest.java b/org.eclipse.handly.examples.basic.ui.tests/src/org/eclipse/handly/internal/examples/basic/ui/model/FooWorkingCopyTest.java index 6795da77..c1b9a05d 100644 --- a/org.eclipse.handly.examples.basic.ui.tests/src/org/eclipse/handly/internal/examples/basic/ui/model/FooWorkingCopyTest.java +++ b/org.eclipse.handly.examples.basic.ui.tests/src/org/eclipse/handly/internal/examples/basic/ui/model/FooWorkingCopyTest.java @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.handly.internal.examples.basic.ui.model; -import static org.eclipse.handly.context.Contexts.*; +import static org.eclipse.handly.context.Contexts.EMPTY_CONTEXT; +import static org.eclipse.handly.context.Contexts.of; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.runtime.CoreException; @@ -26,7 +27,7 @@ import org.eclipse.handly.examples.basic.ui.model.IFooProject; import org.eclipse.handly.examples.basic.ui.model.IFooVar; import org.eclipse.handly.junit.WorkspaceTestCase; import org.eclipse.handly.model.ISourceElementInfo; -import org.eclipse.handly.model.impl.Element; +import org.eclipse.handly.model.impl.IElementImplExtension; import org.eclipse.handly.model.impl.SourceFile; import org.eclipse.handly.model.impl.WorkingCopyInfo; import org.eclipse.handly.util.TextRange; @@ -252,9 +253,9 @@ public class FooWorkingCopyTest { IFooDef def = workingCopy.getDef("f", 0); assertTrue(def.exists()); - ((Element)def).hClose(); + ((IElementImplExtension)def).hClose(); assertNotNull("non-openable elements cannot be closed", - ((Element)def).hPeekAtBody()); + ((IElementImplExtension)def).hPeekAtBody()); } }; // non-openable elements cannot be closed, in working copy or not diff --git a/org.eclipse.handly.examples.basic.ui/src/org/eclipse/handly/internal/examples/basic/ui/model/FooDeltaProcessor.java b/org.eclipse.handly.examples.basic.ui/src/org/eclipse/handly/internal/examples/basic/ui/model/FooDeltaProcessor.java index fcb06a7e..5ac9d2df 100644 --- a/org.eclipse.handly.examples.basic.ui/src/org/eclipse/handly/internal/examples/basic/ui/model/FooDeltaProcessor.java +++ b/org.eclipse.handly.examples.basic.ui/src/org/eclipse/handly/internal/examples/basic/ui/model/FooDeltaProcessor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014, 2016 1C-Soft LLC and others. + * Copyright (c) 2014, 2017 1C-Soft LLC and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -36,8 +36,8 @@ import org.eclipse.handly.examples.basic.ui.model.IFooProject; import org.eclipse.handly.model.IElement; import org.eclipse.handly.model.IElementDelta; import org.eclipse.handly.model.impl.Body; -import org.eclipse.handly.model.impl.Element; import org.eclipse.handly.model.impl.ElementDelta; +import org.eclipse.handly.model.impl.IElementImplExtension; /** * This class is used by the <code>FooModelManager</code> to convert @@ -420,12 +420,12 @@ class FooDeltaProcessor private static Body findBody(IFooElement element) { - return (Body)((Element)element).hFindBody(); + return (Body)((IElementImplExtension)element).hFindBody(); } private static void close(IFooElement element) { - ((Element)element).hClose(); + ((IElementImplExtension)element).hClose(); } private static IResource getResource(IPath fullPath, int resourceType) diff --git a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/DeltaProcessor.java b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/DeltaProcessor.java index 49d7bf20..a26aa802 100644 --- a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/DeltaProcessor.java +++ b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/DeltaProcessor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2016 1C-Soft LLC. + * Copyright (c) 2015, 2017 1C-Soft LLC. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -32,8 +32,8 @@ import org.eclipse.handly.examples.javamodel.JavaModelCore; import org.eclipse.handly.model.IElement; import org.eclipse.handly.model.IElementDelta; import org.eclipse.handly.model.impl.Body; -import org.eclipse.handly.model.impl.Element; import org.eclipse.handly.model.impl.ElementDelta; +import org.eclipse.handly.model.impl.IElementImplExtension; import org.eclipse.jdt.core.IClasspathEntry; /** @@ -605,12 +605,12 @@ class DeltaProcessor private static Body findBody(IJavaElement element) { - return (Body)((Element)element).hFindBody(); + return (Body)((IElementImplExtension)element).hFindBody(); } private static void close(IJavaElement element) { - ((Element)element).hClose(); + ((IElementImplExtension)element).hClose(); } private static IResource getResource(IPath fullPath, int resourceType) diff --git a/org.eclipse.handly/src/org/eclipse/handly/model/impl/Element.java b/org.eclipse.handly/src/org/eclipse/handly/model/impl/Element.java index 99aeef92..94fb3491 100644 --- a/org.eclipse.handly/src/org/eclipse/handly/model/impl/Element.java +++ b/org.eclipse.handly/src/org/eclipse/handly/model/impl/Element.java @@ -53,7 +53,7 @@ import org.eclipse.handly.util.ToStringOptions.FormatStyle; */ public abstract class Element extends PlatformObject - implements IElementImpl, IModelManager.Provider + implements IElementImplExtension, IModelManager.Provider { private final IElement parent; private final String name; @@ -162,99 +162,87 @@ public abstract class Element return hChildren(hBody()); } - /** - * Returns the cached body for this element, or <code>null</code> - * if none. - * - * @return the cached body for this element, or <code>null</code> - * if none - */ + @Override + public IElement[] hChildren(Object body) + { + return ((Body)body).getChildren(); + } + + @Override public Object hFindBody() { return hElementManager().get(this); } - /** - * Returns the cached body for this element without disturbing - * cache ordering, or <code>null</code> if none. - * - * @return the cached body for this element, or <code>null</code> - * if none - */ + @Override public Object hPeekAtBody() { return hElementManager().peek(this); } /** - * Closes this element iff the current state of this element permits closing. - * <p> - * Closing of an element removes its body from the body cache. In general, - * closing of a parent element also closes its children. If the current state - * of an open child element does not permit closing, the child element - * remains open, which generally does not prevent its parent from closing. - * Closing of an element which is not open has no effect. - * </p> + * {@inheritDoc} * <p> - * Shortcut to <code>hClose(EMPTY_CONTEXT)</code>. + * This implementation creates and initializes bodies for this element, + * its ancestors and its children as necessary and then atomically puts + * them into the body cache. * </p> - * - * @see #hClose(IContext) + * @throws CoreException {@inheritDoc} + * @throws OperationCanceledException {@inheritDoc} */ - public final void hClose() - { - hClose(EMPTY_CONTEXT); - } - - /** - * Closing hint. - */ - public enum CloseHint + @Override + public Object hOpen(IContext context, IProgressMonitor monitor) + throws CoreException { - /** - * Closing due to cache overflow. - */ - CACHE_OVERFLOW, - /** - * Closing due to parent closing. - */ - PARENT_CLOSING + if (monitor == null) + monitor = new NullProgressMonitor(); + ElementManager elementManager = hElementManager(); + boolean hadTemporaryCache = elementManager.hasTemporaryCache(); + try + { + Map<IElement, Object> newElements = + elementManager.getTemporaryCache(); + hGenerateBodies(with(of(NEW_ELEMENTS, newElements), context), + monitor); + Object body = newElements.get(this); + if (body == null) + { + // the openable parent did not create a body for this element + throw hDoesNotExistException(); + } + if (monitor.isCanceled()) + throw new OperationCanceledException(); + if (!hadTemporaryCache) + { + if (context.getOrDefault(FORCE_OPEN)) + elementManager.put(this, newElements); + else + { + Object existingBody = elementManager.putIfAbsent(this, + newElements); + if (existingBody != null) + body = existingBody; + } + } + return body; + } + finally + { + if (!hadTemporaryCache) + { + elementManager.resetTemporaryCache(); + } + } } /** - * Close hint property. - * @see #hClose(IContext) - */ - public static final Property<CloseHint> CLOSE_HINT = Property.get( - Element.class.getName() + ".closeHint", //$NON-NLS-1$ - CloseHint.class); - - /** - * Closes this element iff the current state of this element permits closing - * according to options specified in the given context. - * <p> - * Closing of an element removes its body from the body cache. In general, - * closing of a parent element also closes its children. If the current state - * of an open child element does not permit closing, the child element - * remains open, which generally does not prevent its parent from closing. - * Closing of an element which is not open has no effect. - * </p> - * <p> - * Implementations are encouraged to support the following standard options, - * which may be specified in the given context: - * </p> - * <ul> - * <li> - * {@link #CLOSE_HINT} - Closing hint. - * </li> - * </ul> + * {@inheritDoc} * <p> * If the current state of this element permits closing, this implementation * invokes {@link #hRemove(IContext)} method, which closes this element. * </p> - * - * @param context the operation context (not <code>null</code>) */ + @Override public void hClose(IContext context) { CloseHint hint = context.get(CLOSE_HINT); @@ -444,128 +432,6 @@ public abstract class Element IProgressMonitor monitor) throws CoreException; /** - * Returns the cached body for this element. If this element is not - * already present in the body cache, its body will be created, - * initialized, and put in the cache. - * - * @return the cached body for this element (never <code>null</code>) - * @throws CoreException if this element does not exist or if an - * exception occurs while accessing its corresponding resource - */ - protected final Object hBody() throws CoreException - { - return hBody(EMPTY_CONTEXT, null); - } - - /** - * Returns the cached body for this element. If this element is not - * already present in the body cache, its body will be created, - * initialized, and put in the cache. - * - * @param context the operation context (not <code>null</code>) - * @param monitor a progress monitor, or <code>null</code> - * if progress reporting is not desired - * @return the cached body for this element (never <code>null</code>) - * @throws CoreException if this element does not exist or if an - * exception occurs while accessing its corresponding resource - * @throws OperationCanceledException if this method is canceled - */ - protected final Object hBody(IContext context, IProgressMonitor monitor) - throws CoreException - { - Object body = hFindBody(); - if (body != null) - return body; - return hOpen(context, monitor); - } - - /** - * Given a body, returns the immediate children of this element. - * - * @param body the body corresponding to this element - * (never <code>null</code>) - * @return the immediate children of this element (not <code>null</code>) - */ - protected IElement[] hChildren(Object body) - { - return ((Body)body).getChildren(); - } - - /** - * Indicates whether to forcibly reopen this element if it is already open - * (i.e. already present in the body cache). Default value: <code>false</code>. - */ - static final Property<Boolean> FORCE_OPEN = Property.get( - Element.class.getName() + ".forceOpen", Boolean.class).withDefault( //$NON-NLS-1$ - false); - - /** - * Creates and initializes bodies for this element, its ancestors and its - * children as necessary and then atomically puts them into the body cache. - * Returns the cached body for this element. - * <p> - * The following context options influence the operation's behavior: - * </p> - * <ul> - * <li> - * {@link #FORCE_OPEN} - Indicates whether to forcibly reopen this element - * if it is already open (i.e. already present in the body cache). - * </li> - * </ul> - * - * @param context the operation context (not <code>null</code>) - * @param monitor a progress monitor, or <code>null</code> - * if progress reporting is not desired - * @return the cached body for this element (never <code>null</code>) - * @throws CoreException if this element does not exist or if an - * exception occurs while accessing its corresponding resource - * @throws OperationCanceledException if this method is canceled - */ - final Object hOpen(IContext context, IProgressMonitor monitor) - throws CoreException - { - if (monitor == null) - monitor = new NullProgressMonitor(); - ElementManager elementManager = hElementManager(); - boolean hadTemporaryCache = elementManager.hasTemporaryCache(); - try - { - Map<IElement, Object> newElements = - elementManager.getTemporaryCache(); - hGenerateBodies(with(of(NEW_ELEMENTS, newElements), context), - monitor); - Object body = newElements.get(this); - if (body == null) - { - // the openable parent did not create a body for this element - throw hDoesNotExistException(); - } - if (monitor.isCanceled()) - throw new OperationCanceledException(); - if (!hadTemporaryCache) - { - if (context.getOrDefault(FORCE_OPEN)) - elementManager.put(this, newElements); - else - { - Object existingBody = elementManager.putIfAbsent(this, - newElements); - if (existingBody != null) - body = existingBody; - } - } - return body; - } - finally - { - if (!hadTemporaryCache) - { - elementManager.resetTemporaryCache(); - } - } - } - - /** * Returns whether this element is "openable". * <p> * An openable element knows how to open itself on demand (i.e. initialize diff --git a/org.eclipse.handly/src/org/eclipse/handly/model/impl/ElementCache.java b/org.eclipse.handly/src/org/eclipse/handly/model/impl/ElementCache.java index ae18b735..78792b1e 100644 --- a/org.eclipse.handly/src/org/eclipse/handly/model/impl/ElementCache.java +++ b/org.eclipse.handly/src/org/eclipse/handly/model/impl/ElementCache.java @@ -13,8 +13,8 @@ package org.eclipse.handly.model.impl; import static org.eclipse.handly.context.Contexts.of; -import static org.eclipse.handly.model.impl.Element.CLOSE_HINT; -import static org.eclipse.handly.model.impl.Element.CloseHint.CACHE_OVERFLOW; +import static org.eclipse.handly.model.impl.IElementImplExtension.CLOSE_HINT; +import static org.eclipse.handly.model.impl.IElementImplExtension.CloseHint.CACHE_OVERFLOW; import static org.eclipse.handly.util.ToStringOptions.FORMAT_STYLE; import static org.eclipse.handly.util.ToStringOptions.INDENT_POLICY; import static org.eclipse.handly.util.ToStringOptions.FormatStyle.MEDIUM; @@ -95,13 +95,14 @@ public class ElementCache */ protected int getChildCount(IElement element, Object body) { - return ((Element)element).hChildren(body).length; + return ((IElementImplExtension)element).hChildren(body).length; } @Override protected boolean close(LruCacheEntry<IElement, Object> entry) { - ((Element)entry.key).hClose(of(CLOSE_HINT, CACHE_OVERFLOW)); + ((IElementImplExtension)entry.key).hClose(of(CLOSE_HINT, + CACHE_OVERFLOW)); // closing of an element removes it from the cache, so... return false; // ...no need to remove the cache entry after close } diff --git a/org.eclipse.handly/src/org/eclipse/handly/model/impl/ElementDifferencer.java b/org.eclipse.handly/src/org/eclipse/handly/model/impl/ElementDifferencer.java index 862f9084..3e9e4d0a 100644 --- a/org.eclipse.handly/src/org/eclipse/handly/model/impl/ElementDifferencer.java +++ b/org.eclipse.handly/src/org/eclipse/handly/model/impl/ElementDifferencer.java @@ -211,7 +211,7 @@ public class ElementDifferencer Object body; try { - body = ((Element)element).hBody(); + body = ((IElementImplExtension)element).hBody(); } catch (CoreException e) { @@ -220,7 +220,7 @@ public class ElementDifferencer recordBody(body, element); - IElement[] children = ((Element)element).hChildren(body); + IElement[] children = ((IElementImplExtension)element).hChildren(body); insertPositions(children, false); for (IElement child : children) { @@ -302,7 +302,7 @@ public class ElementDifferencer Object newBody; try { - newBody = ((Element)newElement).hBody(); + newBody = ((IElementImplExtension)newElement).hBody(); } catch (CoreException e) { @@ -311,7 +311,8 @@ public class ElementDifferencer findContentChange(oldBody, newBody, newElement); - for (IElement child : ((Element)newElement).hChildren(newBody)) + for (IElement child : ((IElementImplExtension)newElement).hChildren( + newBody)) { findAdditions(child, depth + 1); } diff --git a/org.eclipse.handly/src/org/eclipse/handly/model/impl/ElementManager.java b/org.eclipse.handly/src/org/eclipse/handly/model/impl/ElementManager.java index cd5b6e00..fadc250d 100644 --- a/org.eclipse.handly/src/org/eclipse/handly/model/impl/ElementManager.java +++ b/org.eclipse.handly/src/org/eclipse/handly/model/impl/ElementManager.java @@ -12,8 +12,8 @@ package org.eclipse.handly.model.impl; import static org.eclipse.handly.context.Contexts.EMPTY_CONTEXT; import static org.eclipse.handly.context.Contexts.of; -import static org.eclipse.handly.model.impl.Element.CLOSE_HINT; -import static org.eclipse.handly.model.impl.Element.CloseHint.PARENT_CLOSING; +import static org.eclipse.handly.model.impl.IElementImplExtension.CLOSE_HINT; +import static org.eclipse.handly.model.impl.IElementImplExtension.CloseHint.PARENT_CLOSING; import java.util.HashMap; import java.util.Map; @@ -90,7 +90,7 @@ public class ElementManager */ protected void close(IElement element, IContext context) { - ((Element)element).hClose(context); + ((IElementImplExtension)element).hClose(context); } /** diff --git a/org.eclipse.handly/src/org/eclipse/handly/model/impl/IElementImplExtension.java b/org.eclipse.handly/src/org/eclipse/handly/model/impl/IElementImplExtension.java new file mode 100644 index 00000000..350b2753 --- /dev/null +++ b/org.eclipse.handly/src/org/eclipse/handly/model/impl/IElementImplExtension.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright (c) 2014, 2017 1C-Soft LLC and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vladimir Piskarev (1C) - initial API and implementation + *******************************************************************************/ +package org.eclipse.handly.model.impl; + +import static org.eclipse.handly.context.Contexts.EMPTY_CONTEXT; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.handly.context.IContext; +import org.eclipse.handly.model.IElement; +import org.eclipse.handly.util.Property; + +/** + * Extension of {@link IElementImpl} that introduces the notion of the element's + * cached body. {@link IElement}s may implement this interface. + * + * @noextend This interface is not intended to be extended by clients. + */ +public interface IElementImplExtension + extends IElementImpl +{ + @Override + default IElement[] hChildren() throws CoreException + { + return hChildren(hBody()); + } + + /** + * Given a body, returns the immediate children of this element. + * + * @param body the body corresponding to this element + * (never <code>null</code>) + * @return the immediate children of this element (not <code>null</code>) + */ + IElement[] hChildren(Object body); + + /** + * Returns the cached body for this element, or <code>null</code> + * if none. + * + * @return the cached body for this element, or <code>null</code> + * if none + */ + Object hFindBody(); + + /** + * Returns the cached body for this element without disturbing + * cache ordering, or <code>null</code> if none. + * + * @return the cached body for this element, or <code>null</code> + * if none + */ + Object hPeekAtBody(); + + /** + * Returns the cached body for this element. If this element is not + * already present in the body cache, it will be {@link #hOpen(IContext, + * IProgressMonitor) opened}. Shortcut to <code>hBody(EMPTY_CONTEXT, null)</code>. + * + * @return the cached body for this element (never <code>null</code>) + * @throws CoreException if this element does not exist or if an + * exception occurs while accessing its corresponding resource + */ + default Object hBody() throws CoreException + { + return hBody(EMPTY_CONTEXT, null); + } + + /** + * Returns the cached body for this element. If this element is not + * already present in the body cache, it will be {@link #hOpen(IContext, + * IProgressMonitor) opened} according to options specified in the given + * context. + * + * @param context the operation context (not <code>null</code>) + * @param monitor a progress monitor, or <code>null</code> + * if progress reporting is not desired + * @return the cached body for this element (never <code>null</code>) + * @throws CoreException if this element does not exist or if an + * exception occurs while accessing its corresponding resource + * @throws OperationCanceledException if this method is canceled + */ + default Object hBody(IContext context, IProgressMonitor monitor) + throws CoreException + { + Object body = hFindBody(); + if (body != null) + return body; + return hOpen(context, monitor); + } + + /** + * Indicates whether to forcibly reopen this element if it is already open + * (i.e. already present in the body cache). Default value: <code>false</code>. + * @see #hOpen(IContext, IProgressMonitor) + */ + Property<Boolean> FORCE_OPEN = Property.get( + IElementImplExtension.class.getName() + ".forceOpen", //$NON-NLS-1$ + Boolean.class).withDefault(false); + + /** + * Makes sure this element is open, i.e. it exists and is present in the + * body cache. Performs atomically. Returns the cached body for this element. + * <p> + * Implementations are encouraged to support the following standard options, + * which may be specified in the given context: + * </p> + * <ul> + * <li> + * {@link #FORCE_OPEN} - Indicates whether to forcibly reopen this element + * if it is already open (i.e. already present in the body cache). + * </li> + * </ul> + * + * @param context the operation context (not <code>null</code>) + * @param monitor a progress monitor, or <code>null</code> + * if progress reporting is not desired + * @return the cached body for this element (never <code>null</code>) + * @throws CoreException if this element does not exist or if an + * exception occurs while accessing its corresponding resource + * @throws OperationCanceledException if this method is canceled + */ + Object hOpen(IContext context, IProgressMonitor monitor) + throws CoreException; + + /** + * Closes this element iff the current state of this element permits closing. + * <p> + * Closing of an element removes its body from the body cache. In general, + * closing of a parent element also closes its children. If the current state + * of an open child element does not permit closing, the child element + * remains open, which generally does not prevent its parent from closing. + * Closing of an element which is not open has no effect. + * </p> + * <p> + * Shortcut to <code>hClose(EMPTY_CONTEXT)</code>. + * </p> + * + * @see #hClose(IContext) + */ + default void hClose() + { + hClose(EMPTY_CONTEXT); + } + + /** + * Closing hint. + */ + enum CloseHint + { + /** + * Closing due to cache overflow. + */ + CACHE_OVERFLOW, + /** + * Closing due to parent closing. + */ + PARENT_CLOSING + } + + /** + * Close hint property. + * @see #hClose(IContext) + */ + Property<CloseHint> CLOSE_HINT = Property.get( + IElementImplExtension.class.getName() + ".closeHint", //$NON-NLS-1$ + CloseHint.class); + + /** + * Closes this element iff the current state of this element permits closing + * according to options specified in the given context. + * <p> + * Closing of an element removes its body from the body cache. In general, + * closing of a parent element also closes its children. If the current state + * of an open child element does not permit closing, the child element + * remains open, which generally does not prevent its parent from closing. + * Closing of an element which is not open has no effect. + * </p> + * <p> + * Implementations are encouraged to support the following standard options, + * which may be specified in the given context: + * </p> + * <ul> + * <li> + * {@link #CLOSE_HINT} - Closing hint. + * </li> + * </ul> + * + * @param context the operation context (not <code>null</code>) + */ + void hClose(IContext context); +} diff --git a/org.eclipse.handly/src/org/eclipse/handly/model/impl/ISourceConstructImplExtension.java b/org.eclipse.handly/src/org/eclipse/handly/model/impl/ISourceConstructImplExtension.java new file mode 100644 index 00000000..17f87e33 --- /dev/null +++ b/org.eclipse.handly/src/org/eclipse/handly/model/impl/ISourceConstructImplExtension.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2014, 2017 1C-Soft LLC and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Vladimir Piskarev (1C) - initial API and implementation + *******************************************************************************/ +package org.eclipse.handly.model.impl; + +/** + * Extension of {@link ISourceConstructImpl} that introduces the notion of + * the element's occurrence count. {@code ISourceConstruct}s may implement + * this interface. + * + * @noextend This interface is not intended to be extended by clients. + */ +public interface ISourceConstructImplExtension + extends ISourceConstructImpl +{ + /** + * Returns the count used to uniquely identify this element in the case + * that a duplicate named element exists. The occurrence count starts at 1 + * (thus the first occurrence is occurrence 1, not occurrence 0). + * + * @return the occurrence count for this element + */ + int hOccurrenceCount(); + + /** + * Increments the occurrence count of this element. + * <p> + * This method is intended to be used only when building structure of + * a source file to distinguish source constructs with duplicate names. + * </p> + */ + void hIncrementOccurrenceCount(); +} diff --git a/org.eclipse.handly/src/org/eclipse/handly/model/impl/SourceConstruct.java b/org.eclipse.handly/src/org/eclipse/handly/model/impl/SourceConstruct.java index 1bf042ac..67f9b321 100644 --- a/org.eclipse.handly/src/org/eclipse/handly/model/impl/SourceConstruct.java +++ b/org.eclipse.handly/src/org/eclipse/handly/model/impl/SourceConstruct.java @@ -20,7 +20,7 @@ import org.eclipse.handly.model.IElement; */ public abstract class SourceConstruct extends SourceElement - implements ISourceConstructImpl + implements ISourceConstructImplExtension { private int occurrenceCount = 1; @@ -48,29 +48,14 @@ public abstract class SourceConstruct && occurrenceCount == ((SourceConstruct)obj).occurrenceCount; } - /** - * Returns the count used to uniquely identify this element in the case - * that a duplicate named element exists. The occurrence count starts at 1 - * (thus the first occurrence is occurrence 1, not occurrence 0). - * - * @return the occurrence count for this element - */ + @Override public final int hOccurrenceCount() { return occurrenceCount; } - /** - * Increments the occurrence count of this element. - * <p> - * This method is intended to be used only when building structure of - * a source file to distinguish source constructs with duplicate names. - * </p> - * - * @see #hOccurrenceCount() - * @see StructureHelper - */ - public final void hIncrementOccurrenceCount() + @Override + public void hIncrementOccurrenceCount() { occurrenceCount++; } diff --git a/org.eclipse.handly/src/org/eclipse/handly/model/impl/StructureHelper.java b/org.eclipse.handly/src/org/eclipse/handly/model/impl/StructureHelper.java index 0d39bfc4..a271128e 100644 --- a/org.eclipse.handly/src/org/eclipse/handly/model/impl/StructureHelper.java +++ b/org.eclipse.handly/src/org/eclipse/handly/model/impl/StructureHelper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014, 2016 1C-Soft LLC and others. + * Copyright (c) 2014, 2017 1C-Soft LLC and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -19,15 +19,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.handly.context.IContext; import org.eclipse.handly.model.Elements; import org.eclipse.handly.model.IElement; /** - * A helper class for building the structure of {@link Element#hIsOpenable() - * openable} elements that have non-openable children. Typically, this class - * is utilized for building the structure of source files. + * A helper class for building a subtree of elements. Typically, this class + * is used when building the entire structure of a source file. * <p> * The structure is being created as calls to {@link #addChild(Body, IElement, * Object)} are made on the helper. Make sure to complete initialization of each @@ -37,8 +34,6 @@ import org.eclipse.handly.model.IElement; * Clients can use this class as it stands or subclass it * as circumstances warrant. * </p> - * - * @see Element#hBuildStructure(IContext, IProgressMonitor) */ public class StructureHelper { @@ -74,8 +69,7 @@ public class StructureHelper * @param parentBody the body of the parent element (not <code>null</code>) * @param child the handle for the child element (not <code>null</code>) * @param childBody the body for the child element, or <code>null</code> - * if no body is to be associated with the child element (e.g. if the - * child is an {@link Element#hIsOpenable() openable} element) + * if no body is to be associated with the child element */ public void addChild(Body parentBody, IElement child, Object childBody) { @@ -118,19 +112,20 @@ public class StructureHelper /** * Allows to make distinctions among elements which would otherwise be equal. * <p> - * If the given element is a <code>SourceConstruct</code> which is equal to - * an already {@link #addChild added} element, this implementation increments - * its {@link SourceConstruct#hOccurrenceCount() occurrence count} until - * it is no longer equal to any previously added element. + * If the given element is a source construct which is equal to an already + * {@link #addChild added} element, this implementation increments its + * {@link ISourceConstructImplExtension#hOccurrenceCount() occurrence count} + * until it is no longer equal to any previously added element. * </p> * * @param element the given element (never <code>null</code>) */ protected void resolveDuplicates(IElement element) { - if (!(element instanceof SourceConstruct)) + if (!(element instanceof ISourceConstructImplExtension)) return; - SourceConstruct sc = (SourceConstruct)element; + ISourceConstructImplExtension sc = + (ISourceConstructImplExtension)element; while (newElements.containsKey(sc)) sc.hIncrementOccurrenceCount(); } |