/* * Copyright (c) 2013, the Dart project authors. * * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html * * 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 com.google.dart.engine.internal.task; import com.google.dart.engine.ast.CompilationUnit; import com.google.dart.engine.context.AnalysisException; import com.google.dart.engine.element.CompilationUnitElement; import com.google.dart.engine.element.LibraryElement; import com.google.dart.engine.internal.context.InternalAnalysisContext; import com.google.dart.engine.internal.context.PerformanceStatistics; import com.google.dart.engine.internal.context.RecordingErrorListener; import com.google.dart.engine.internal.context.ResolvableCompilationUnit; import com.google.dart.engine.internal.error.ErrorReporter; import com.google.dart.engine.internal.resolver.DeclarationResolver; import com.google.dart.engine.internal.resolver.InheritanceManager; import com.google.dart.engine.internal.resolver.ResolverVisitor; import com.google.dart.engine.internal.resolver.TypeProvider; import com.google.dart.engine.internal.resolver.TypeResolverVisitor; import com.google.dart.engine.internal.verifier.ConstantVerifier; import com.google.dart.engine.internal.verifier.ErrorVerifier; import com.google.dart.engine.source.Source; import com.google.dart.engine.utilities.general.TimeCounter.TimeCounterHandle; /** * Instances of the class {@code ResolveDartUnitTask} resolve a single Dart file based on a existing * element model. */ public class ResolveDartUnitTask extends AnalysisTask { /** * The source that is to be resolved. */ private Source source; /** * The element model for the library containing the source. */ private LibraryElement libraryElement; /** * The time at which the contents of the source were last modified. */ private long modificationTime = -1L; /** * The compilation unit that was resolved by this task. */ private CompilationUnit resolvedUnit; /** * Initialize a newly created task to perform analysis within the given context. * * @param context the context in which the task is to be performed * @param source the source to be parsed * @param libraryElement the element model for the library containing the source */ public ResolveDartUnitTask(InternalAnalysisContext context, Source source, LibraryElement libraryElement) { super(context); this.source = source; this.libraryElement = libraryElement; } @Override public <E> E accept(AnalysisTaskVisitor<E> visitor) throws AnalysisException { return visitor.visitResolveDartUnitTask(this); } /** * Return the source for the library containing the source that is to be resolved. * * @return the source for the library containing the source that is to be resolved */ public Source getLibrarySource() { return libraryElement.getSource(); } /** * Return the time at which the contents of the source that was parsed were last modified, or a * negative value if the task has not yet been performed or if an exception occurred. * * @return the time at which the contents of the source that was parsed were last modified */ public long getModificationTime() { return modificationTime; } /** * Return the compilation unit that was resolved by this task. * * @return the compilation unit that was resolved by this task */ public CompilationUnit getResolvedUnit() { return resolvedUnit; } /** * Return the source that is to be resolved. * * @return the source to be resolved */ public Source getSource() { return source; } @Override protected String getTaskDescription() { Source librarySource = libraryElement.getSource(); if (librarySource == null) { return "resolve unit null source"; } return "resolve unit " + librarySource.getFullName(); } @Override protected void internalPerform() throws AnalysisException { TypeProvider typeProvider = ((InternalAnalysisContext) libraryElement.getContext()).getTypeProvider(); ResolvableCompilationUnit resolvableUnit = getContext().computeResolvableCompilationUnit(source); modificationTime = resolvableUnit.getModificationTime(); CompilationUnit unit = resolvableUnit.getCompilationUnit(); if (unit == null) { throw new AnalysisException( "Internal error: computeResolvableCompilationUnit returned a value without a parsed Dart unit"); } // // Resolve names in declarations. // new DeclarationResolver().resolve(unit, find(libraryElement, source)); // // Resolve the type names. // RecordingErrorListener errorListener = new RecordingErrorListener(); TypeResolverVisitor typeResolverVisitor = new TypeResolverVisitor( libraryElement, source, typeProvider, errorListener); unit.accept(typeResolverVisitor); // // Resolve the rest of the structure // InheritanceManager inheritanceManager = new InheritanceManager(libraryElement); ResolverVisitor resolverVisitor = new ResolverVisitor( libraryElement, source, typeProvider, inheritanceManager, errorListener); unit.accept(resolverVisitor); // // Perform additional error checking. // TimeCounterHandle counterHandleErrors = PerformanceStatistics.errors.start(); try { ErrorReporter errorReporter = new ErrorReporter(errorListener, source); ErrorVerifier errorVerifier = new ErrorVerifier( errorReporter, libraryElement, typeProvider, inheritanceManager); unit.accept(errorVerifier); ConstantVerifier constantVerifier = new ConstantVerifier( errorReporter, libraryElement, typeProvider); unit.accept(constantVerifier); } finally { counterHandleErrors.stop(); } // // Capture the results. // resolvedUnit = unit; } /** * Search the compilation units that are part of the given library and return the element * representing the compilation unit with the given source. Return {@code null} if there is no * such compilation unit. * * @param libraryElement the element representing the library being searched through * @param unitSource the source for the compilation unit whose element is to be returned * @return the element representing the compilation unit */ private CompilationUnitElement find(LibraryElement libraryElement, Source unitSource) { CompilationUnitElement element = libraryElement.getDefiningCompilationUnit(); if (element.getSource().equals(unitSource)) { return element; } for (CompilationUnitElement partElement : libraryElement.getParts()) { if (partElement.getSource().equals(unitSource)) { return partElement; } } return null; } }