| /*=============================================================================# |
| # Copyright (c) 2009, 2021 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.ltk.model.core.build; |
| |
| import java.util.concurrent.CancellationException; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.lang.Nullable; |
| |
| import org.eclipse.statet.ltk.ast.core.AstInfo; |
| import org.eclipse.statet.ltk.core.Ltk; |
| import org.eclipse.statet.ltk.core.SourceContent; |
| import org.eclipse.statet.ltk.core.WorkingContext; |
| import org.eclipse.statet.ltk.issues.core.IssueRequestor; |
| import org.eclipse.statet.ltk.issues.core.IssueTypeSet; |
| import org.eclipse.statet.ltk.issues.core.impl.ResourceMarkerIssueRequestor; |
| import org.eclipse.statet.ltk.model.core.ModelManager; |
| import org.eclipse.statet.ltk.model.core.element.SourceUnit; |
| import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo; |
| import org.eclipse.statet.ltk.model.core.element.WorkspaceSourceUnit; |
| |
| |
| @NonNullByDefault |
| public abstract class SourceUnitModelContainer<TSourceUnit extends SourceUnit, TModelInfo extends SourceUnitModelInfo> { |
| |
| |
| private final @Nullable WorkingContext mode; |
| |
| private final TSourceUnit unit; |
| |
| private @Nullable AstInfo astInfo; |
| |
| private @Nullable TModelInfo modelInfo; |
| |
| |
| public SourceUnitModelContainer(final TSourceUnit unit) { |
| this.unit= unit; |
| this.mode= getMode(unit); |
| } |
| |
| |
| public abstract boolean isContainerFor(String modelTypeId); |
| |
| public abstract Class<?> getAdapterClass(); |
| |
| public @Nullable IssueTypeSet getIssueTypeSet() { |
| return null; |
| } |
| |
| |
| protected @Nullable WorkingContext getMode(final TSourceUnit su) { |
| if (su instanceof WorkspaceSourceUnit) { |
| return su.getWorkingContext(); |
| } |
| return null; |
| } |
| |
| protected final @Nullable WorkingContext getMode() { |
| return this.mode; |
| } |
| |
| |
| public TSourceUnit getSourceUnit() { |
| return this.unit; |
| } |
| |
| public SourceContent getParseContent(final IProgressMonitor monitor) { |
| return this.unit.getContent(monitor); |
| } |
| |
| public @Nullable AstInfo getAstInfo(final boolean ensureSync, final IProgressMonitor monitor) { |
| if (ensureSync) { |
| try { |
| getModelManager().reconcile(this, ModelManager.AST, monitor); |
| } |
| catch (final CancellationException e) {} |
| } |
| return this.astInfo; |
| } |
| |
| public @Nullable TModelInfo getModelInfo(final int syncLevel, final IProgressMonitor monitor) { |
| if ((syncLevel & ModelManager.REFRESH) != 0) { |
| clear(); |
| } |
| if ((syncLevel & 0xf) >= ModelManager.MODEL_FILE) { |
| final @Nullable TModelInfo currentModel= this.modelInfo; |
| if ((syncLevel & ModelManager.RECONCILE) != 0 |
| || currentModel == null |
| || currentModel.getStamp().getContentStamp() == 0 |
| || currentModel.getStamp().getContentStamp() != this.unit.getContentStamp(monitor) ) { |
| try { |
| getModelManager().reconcile(this, syncLevel, monitor); |
| } |
| catch (final CancellationException e) {} |
| } |
| } |
| return this.modelInfo; |
| } |
| |
| protected abstract ModelManager getModelManager(); |
| |
| |
| public void clear() { |
| this.astInfo= null; |
| this.modelInfo= null; |
| } |
| |
| public @Nullable AstInfo getCurrentAst() { |
| if (this.mode == Ltk.PERSISTENCE_CONTEXT) { |
| final @Nullable TModelInfo model= getCurrentModel(); |
| if (model != null) { |
| return model.getAst(); |
| } |
| return null; |
| } |
| return this.astInfo; |
| } |
| |
| public void setAst(final AstInfo ast) { |
| if (this.mode == Ltk.PERSISTENCE_CONTEXT) { |
| return; |
| } |
| this.astInfo= ast; |
| } |
| |
| public @Nullable TModelInfo getCurrentModel() { |
| return this.modelInfo; |
| } |
| |
| public void setModel(final @Nullable TModelInfo modelInfo) { |
| final AstInfo astInfo; |
| if (modelInfo != null |
| && ((astInfo= this.astInfo) == null || astInfo.getStamp().equals(modelInfo.getAst().getStamp())) ) { |
| // otherwise, the ast is probably newer |
| setAst(modelInfo.getAst()); |
| } |
| this.modelInfo= modelInfo; |
| } |
| |
| |
| public void clearIssues() throws CoreException { |
| final var mode= getMode(); |
| if (mode == Ltk.PERSISTENCE_CONTEXT) { |
| final IssueTypeSet issueTypeSet= getIssueTypeSet(); |
| if (issueTypeSet != null) { |
| ResourceMarkerIssueRequestor.clear(getSourceUnit().getResource(), issueTypeSet); |
| } |
| } |
| } |
| |
| public @Nullable IssueRequestor createIssueRequestor() { |
| final var mode= getMode(); |
| if (mode == Ltk.PERSISTENCE_CONTEXT) { |
| final IssueTypeSet issueTypeSet= getIssueTypeSet(); |
| if (issueTypeSet != null) { |
| return ResourceMarkerIssueRequestor.create(getSourceUnit().getResource(), issueTypeSet); |
| } |
| } |
| return null; |
| } |
| |
| } |