Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  classpath_element.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * 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 java

import (
 "fmt"
 "strings"

 "android/soong/android"
)

// Supports constructing a list of ClasspathElement from a set of fragments and modules.

// ClasspathElement represents a component that contributes to a classpath. That can be
// either a java module or a classpath fragment module.
type ClasspathElement interface {
 Module() android.ModuleProxy
 String() string
}

type ClasspathElements []ClasspathElement

// ClasspathFragmentElement is a ClasspathElement that encapsulates a classpath fragment module.
type ClasspathFragmentElement struct {
 Fragment android.ModuleProxy
 Contents []android.ModuleProxy
}

func (b *ClasspathFragmentElement) Module() android.ModuleProxy {
 return b.Fragment
}

func (b *ClasspathFragmentElement) String() string {
 contents := []string{}
 for _, module := range b.Contents {
  contents = append(contents, module.String())
 }
 return fmt.Sprintf("fragment(%s, %s)", b.Fragment, strings.Join(contents, ", "))
}

var _ ClasspathElement = (*ClasspathFragmentElement)(nil)

// ClasspathLibraryElement is a ClasspathElement that encapsulates a java library.
type ClasspathLibraryElement struct {
 Library android.ModuleProxy
}

func (b *ClasspathLibraryElement) Module() android.ModuleProxy {
 return b.Library
}

func (b *ClasspathLibraryElement) String() string {
 return fmt.Sprintf("library{%s}", b.Library)
}

var _ ClasspathElement = (*ClasspathLibraryElement)(nil)

// ClasspathElementContext defines the context methods needed by CreateClasspathElements
type ClasspathElementContext interface {
 android.OtherModuleProviderContext
 ModuleErrorf(fmt string, args ...interface{})
}

// CreateClasspathElements creates a list of ClasspathElement objects from a list of libraries and
// a list of fragments.
//
// The libraries parameter contains the set of libraries from which the classpath is constructed.
// The fragments parameter contains the classpath fragment modules whose contents are libraries that
// are part of the classpath. Each library in the libraries parameter may be part of a fragment. The
// determination as to which libraries belong to fragments and which do not is based on the apex to
// which they belong, if any.
//
// Every fragment in the fragments list must be part of one or more apexes and each apex is assumed
// to contain only a single fragment from the fragments list. A library in the libraries parameter
// that is part of an apex must be provided by a classpath fragment in the corresponding apex.
//
// This will return a ClasspathElements list that contains a ClasspathElement for each standalone
// library and each fragment. The order of the elements in the list is such that if the list was
// flattened into a list of library modules that it would result in the same list or modules as the
// input libraries. Flattening the list can be done by replacing each ClasspathFragmentElement in
// the list with its Contents field.
//
// Requirements/Assumptions:
//   - A fragment can be associated with more than one apex but each apex must only be associated with
//     a single fragment from the fragments list.
//   - All of a fragment's contents must appear as a contiguous block in the same order in the
//     libraries list.
//   - Each library must only appear in a single fragment.
//
// The apex is used to identify which libraries belong to which fragment. First a mapping is created
// from apex to fragment. Then the libraries are iterated over and any library in an apex is
// associated with an element for the fragment to which it belongs. Otherwise, the libraries are
// standalone and have their own element.
//
// e.g. Given the following input:
//
//  libraries: core-oj, core-libart, framework, ext
//  fragments: art-bootclasspath-fragment
//     libraryToApex: core-oj: com.android.art, core-libart: com.android.art
//     apexNameToFragment: com.android.art: art-bootclasspath-fragment
//
// Then this will return:
//
// ClasspathFragmentElement(art-bootclasspath-fragment, [core-oj, core-libart]),
// ClasspathLibraryElement(framework),
// ClasspathLibraryElement(ext),
func CreateClasspathElements(ctx ClasspathElementContext, libraries []android.ModuleProxy, fragments []android.ModuleProxy,
 libraryToApex map[android.ModuleProxy]string, apexNameToFragment map[string]android.ModuleProxy) ClasspathElements {

 fragmentToElement := map[android.ModuleProxy]*ClasspathFragmentElement{}
 elements := []ClasspathElement{}
 var currentElement ClasspathElement

skipLibrary:
 // Iterate over the libraries to construct the ClasspathElements list.
 for _, library := range libraries {
  var element ClasspathElement
  if libraryApex, ok := libraryToApex[library]; ok {
   var fragment android.ModuleProxy

   // Make sure that the library is in only one fragment of the classpath.
   if f, ok := apexNameToFragment[libraryApex]; ok {
    if fragment.IsNil() {
     // This is the first fragment so just save it away.
     fragment = f
    } else if f != fragment {
     // This apex variant of the library is in a different fragment.
     ctx.ModuleErrorf("library %s is in two separate fragments, %s and %s", library, fragment, f)
     // Skip over this library entirely as otherwise the resulting classpath elements would
     // be invalid.
     continue skipLibrary
    }
   } else {
    // There is no fragment associated with the library's apex.
   }

   if fragment.IsNil() {
    ctx.ModuleErrorf("library %s is from apexes %s which have no corresponding fragment in %s",
     library, []string{libraryApex}, fragments)
    // Skip over this library entirely as otherwise the resulting classpath elements would
    // be invalid.
    continue skipLibrary
   } else if existingFragmentElement, ok := fragmentToElement[fragment]; ok {
    // This library is in a fragment element that has already been added.

    // If the existing fragment element is still the current element then this library is
    // contiguous with other libraries in that fragment so there is nothing more to do.
    // Otherwise this library is not contiguous with other libraries in the same fragment which
    // is an error.
    if existingFragmentElement != currentElement {
     separator := ""
     if fragmentElement, ok := currentElement.(*ClasspathFragmentElement); ok {
      separator = fmt.Sprintf("libraries from fragment %s like %s", fragmentElement.Fragment, fragmentElement.Contents[0])
     } else {
      libraryElement := currentElement.(*ClasspathLibraryElement)
      separator = fmt.Sprintf("library %s", libraryElement.Library)
     }

     // Get the library that precedes this library in the fragment. That is the last library as
     // this library has not yet been added.
     precedingLibraryInFragment := existingFragmentElement.Contents[len(existingFragmentElement.Contents)-1]
     ctx.ModuleErrorf("libraries from the same fragment must be contiguous, however %s and %s from fragment %s are separated by %s",
      precedingLibraryInFragment, library, fragment, separator)
    }

    // Add this library to the fragment element's contents.
    existingFragmentElement.Contents = append(existingFragmentElement.Contents, library)
   } else {
    // This is the first library in this fragment so add a new element for the fragment,
    // including the library.
    fragmentElement := &ClasspathFragmentElement{
     Fragment: fragment,
     Contents: []android.ModuleProxy{library},
    }

    // Store it away so we can detect when attempting to create another element for the same
    // fragment.
    fragmentToElement[fragment] = fragmentElement
    element = fragmentElement
   }
  } else {
   // The library is from the platform so just add an element for it.
   element = &ClasspathLibraryElement{Library: library}
  }

  // If no element was created then it means that the library has been added to an existing
  // fragment element so the list of elements and current element are unaffected.
  if element != nil {
   // Add the element to the list and make it the current element for the next iteration.
   elements = append(elements, element)
   currentElement = element
  }
 }

 return elements
}

[Dauer der Verarbeitung: 0.22 Sekunden, vorverarbeitet 2026-06-28]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik